Florian Reichle
Angaben zu den Daten
Das verwendete Dataset des Projekts: https://www.kaggle.com/datasets/gregorut/videogamesales
Dies besteht aus den Daten von https://www.vgchartz.com/ für die Jahre 1980 bis 2016
und umfasst die Folgenden Spalten bzw.Daten.
- Rank - Die Platzierung des Spiels nach Anzahl der Verkäufen
- Name - Der Name des Spiels
- Platform - Die Platform auf der das Spiel veröffentlicht wurde (z.B.
PC,PS4, etc.)
- Year - Das Jahr der Veröffentlichung des Spiels
- Genre - Das Genre des Spiels (z.B. Sport,Action, Puzzle)
- Publisher - Der Publisher des Spiels
- NA_Sales - Die Anzahl der Verkäufe in Nord-Amerika (in
millionen)
- EU_Sales - Die Anzahl der Verkäufe in Europa (in millionen)
- JP_Sales - Die Anzahl der Verkäufe in Japan (in millionen)
- Other_Sales - Die Anzahl der Verkäufe im Rest der Welt (in
millionen)
- Global_Sales - Die Anzahl der Verkäufe Weltweit (in millionen)
Inhaltsverzeichnis
- Releaseanalyse
- Platformanalyse
- Publisheranalyse
- Genreanalyse
- Genreverteilung pro Jahr
- Publisher Genres
- Kritischer Rückblick
Thesen
Bevor wir mit der Analyse der Daten beginnen können Stellen wir
erstmal ein paar Thesen bzw. Fragestellungen auf die wir im laufe des
Projekts hinterfragen bzw beantworten wollen.
Welche Jahre sind die besten in der Anzahl der releasten Games
und Sales? Antwort
Werden heutzutage mehr Spiele Releast und Verkauft als noch 1980?
Antwort
Welche Jahre sind die besten in Anzahl Sales pro Game? Werden
neuere Spiele automatisch mehr Gekauft? Antwort
Welche Plattform ist die beste in Anzahl verkäufen? Welche in
Anzahl der Game Releases? Antwort
Haben Ältere Platformen Automatisch mehr Spiele und Verkäufe? Antwort
Favorisieren verschiedene Regionen verschiedene Platformen?
Verkaufen die Regionenheimischen Platformen automatisch auch die meisten
Spiele? Antwort
Wie Entwickeln sich die Verkäufe pro Platform im laufe der Jahre?
Haben Platformen kurz nach Release den größten “Hype”? Antwort
Bestimmte Publisher häufen sich in Anzahl der Spiele und der
Verkäufen (z.B. Nintendo, EA, Activision Blizzard) Antwort
Gibt es regionale Unterschiede in den Publishern? Werden
Regioneninterne Publisher Favoritisiert? Antwort
Wie sind die Genres der Spiele verteilt? Häufen sich bestimmte
Genres bei Anzahl und Verkaufszahlen? Gibt es Genres die
besser/schlechter Performen als sie sollten? Antwort
Gibt es regionale Unterschiede in den Genres? (Gibt es Regionen
die Spezifische Genres Favorisieren welche in anderen Regionen nur eine
geringe Rolle spielt?) Antwort
Wie haben sich die Genres über die Jahre entwickelt? Antwort
Gibt es Genres die mal großen Einfluss hatten und nun
Bedeutungslos sind? Antwort
Gibt es Publisher die bestimmte Genres bevorzugen bzw. Publisher
deren Games eines bestimmten Genres sich besonders gut Verkaufen? Antwort
Daten und Librarys
Nach dem Vorstellen der Daten und dem aufstellen der initialen Thesen
können wir nun mit dem einlesen der Daten beginnen.
Zusätzlich erstellen wir noch eine Farbpalette und importieren die
Librarys
library(readr)
library(tidyverse)
library(forcats)
library(plotly)
library(knitr, warn.conflicts = FALSE, quietly=TRUE)
library(RColorBrewer)
library(stringr)
library(dygraphs)
library(xts)
suppressPackageStartupMessages(library(dplyr))
myPalette <- brewer.pal(10, "Paired")
vgsales <- read_csv("vgsales.csv")
Rows: 16598 Columns: 11
── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (5): Name, Platform, Year, Genre, Publisher
dbl (6): Rank, NA_Sales, EU_Sales, JP_Sales, Other_Sales, Global_Sales
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Videospiel releases
Videospiel releases im laufe der Jahre
Releases nach Anzahl
Unsere erste These war “Welche Jahre sind die besten in der Anzahl
der releasten Games und Sales?” Um dieser Fragestellung auf den Grund zu
gehen müssen wir zuerst einmal die Daten der Tabelle vgsales mithilfe
der Funktion group_by(Year) anhand der Jahre Zusammenfassen.
Nun erhalten wir eine nach den Jahren zusammengefasste Tabelle deren
Einträge wir mit der Funktion dplyr::summarize(Anzahl =n())
abzählen und als Wert Anzahl abspeichern. Aufgrund der für diese analyse
Fehlerhaften Daten verwenden wir noch die Funktion filter() um
alle fehlenden Jahreseinträge sowie die Jahre 2020 und 2017
herauszufiltern. Letztere Jahre sind daher fehlerhaft, da der Datensatz
2016 erstellt wurde. Diese Daten speichern wir als data.frame
in der Variable grouped ab. Im Folgenden verwenden wir
ebenjenes data.frame um nur die Einträge Jahr und Anzahl zu selektieren
und in der Variable filtered abzuspeichern. Die erhaltene
Tabelle hat nun zwei Spalten: Jahr und Anzahl. Des Weiteren erstellen
wir zwei weitere Variablen ax und aywelche beide eine
Liste mit nur einem Attribut sind: “Title”. Nun verwenden wir
plot_ly() um mithilfe der type = ‘scatter’ und
mode = ‘lines’ Parameter ein Liniendiagramm zu erstellen.
Außerdem nutzen wir die layout() funktion um einen Titel zu
erstellen, sowie mithilfe unsere beiden Variablen ax und ay die Achsen
zu beschriften.
grouped <- vgsales %>%
group_by(Year) %>%
dplyr::summarize(Anzahl =n()) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
filtered <- grouped %>% select(Year,Anzahl)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "Anzahl"
)
filtered %>%
plot_ly(x = ~Year, y = ~Anzahl, type = 'scatter', mode = 'lines', fill = 'tozeroy' ,colors = myPalette) %>%
layout(title="Anzahl der Spielereleases von 1980-2016",
xaxis = ax,
yaxis = ay
)
NA
Betrachten wir einmal das entstandene Diagramm. Zwischen 1980 und
1993 sind hier kaum Unterschiede festzustellen und die Schwankungen
können aufgrund der geringen Zahl der Veröffentlichungen (zwischen 14
und 49) vernachlässigt werden. Ab 1993 können wir dann ein stetiges
Wachstum feststellen welches 1998 vorerst den Höchstwert erreicht. In
den Jahren 1999 und 2000 geht die Anzahl erst einmal leicht zurück bevor
sich der Wert bis 2002 von 349 auf 829 mehr als verdoppelt. Bis 2004 ist
wiederum ein leichter Rückgang festzustellen auf welchem ein Stetiges
Wachstum zum Höchstwert von 1428 (2008) sowie 1431 (2009) folgt. Danach
folgt ein extremer und mit Unterbrechung von 2014 (582) und 2015 (614)
stetiger Rückgang in den Release Zahlen auf einen Stand von 344 im Jahr
2016.
Sehen wir uns diese Zahlen einmal genauer an kommt die Frage auf
Woran diese Extremen Zahlen in den Veröffentlichungen zurückzuführen
sind? An diesem Punkt der Analyse können wir nur spekulieren die Spitzen
könnten allerdings an den Veröffentlichungen großer, den Markt
bestimmenden Plattformen wie der PS2/3, der Xbox und den Plattformen von
Nintendo wie Gamecube oder Wii zurückzuführen sein. Hierzu aber später
mehr.
Releases nach Verkaufszahlen
Um dem zweiten Teil der Fragestellung auf den Grund gehen zu können
müssen wir erneut die Daten der Tabelle vgsales mithilfe der Funktion
group_by(Year) anhand der Jahre Zusammenfassen. Nun erhalten
wir wieder die nach den Jahren zusammengefasste Tabelle deren Einträge
wir mit der Funktion dplyr::summarize(gr_sum =
sum(Global_Sales)) zusammenfassen. Dem Aufmerksamen Leser wird
auffallen das hier ein kleiner aber feiner Unterschied zum vorherigen
Aufruf besteht. Statt Anzahl =n() nutzen wir hier gr_sum =
sum(Global_Sales). Diese Funktion summiert alle Werte der Spalte
Global_Sales auf und speichert den den Wert in die Spalte
gr_sum. Aufgrund der für diese analyse weiterhin Fehlerhaften
Daten verwenden wir erneut die Funktion filter() um alle
fehlenden Jahreseinträge sowie die Jahre 2020 und 2017 herauszufiltern.
Diese Daten speichern wir wieder als data.frame in der Variable
grouped ab. Im folgenden verwenden wir ebenjenes data.frame um
nur die Einträge Jahr und gr_sum zu selektieren und in der
Variable filtered abzuspeichern. Die erhaltene Tabelle hat nun
zwei Spalten: Jahr und gr_sum. Desweiteren erstellen wir erneut
die Variablen ax und ay. Nun verwenden wir
plot_ly() um mithilfe der type = ‘scatter’ und
mode = ‘lines’ Parameter ein Liniendiagramm zu erstellen.
Außerdem nutzen wir die layout() funktion um einen titel zu
erstellen, sowie mithilfe unsere beiden Variablen ax und ay die Achsen
zu beschriften.
grouped <- vgsales %>%
group_by(Year) %>%
dplyr::summarize(gr_sum = sum(Global_Sales)) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
filtered <- grouped %>% select(Year,gr_sum)
ax <- list(
title = "Jahr"
)
ay <- list(
title = " Verkäufe pro Jahr (in mio)"
)
filtered %>%
plot_ly(x = ~Year, y = ~gr_sum, type = 'scatter', mode = 'lines', fill = 'tozeroy' ,colors = myPalette) %>%
layout(title="Videospielverkäufe von 1980-2016",
xaxis = ax,
yaxis = ay
)
NA
Betrachten wir nun das entstandene Diagramm fällt uns zuerst auf,
dass es dem vorherigen recht ähnlich sieht. Dies ist kaum verwunderlich
und stellt keinen nennenswerten Wissensgewinn da. Der wohl
Nenneswerteste unterschied ist das Fehlen des Anstiegs, welcher in der
Anzahl der Gamereleases zum Jahr 2015 festzustellen war. Durch den
direkten Vergleich ist dies allerdings ein guter Zeitpunkt um uns mit
unserer Zweiten These auseinanderzusetzen. “Werden heutzutage mehr
Spiele Releast und Verkauft als noch 1980?”. Diese sehen wir
aufjedenfall bestätigt obwohl Festzustellen ist, dass die besten Jahre
sowohl in verkäufen als auch in der Anzahl die Jahre 2008 und 2009
waren. Dies Wirft natürlich die Frage auf was der Grund für diesen
Verlauf ist und wäre ein Interessanter ansatz für eine weitere Arbeit.
Verkaufszahlen pro Spiel
Die Frage die Wir allerdings beantworten können ist “Werden
neuere Spiele automatisch mehr Gekauft?”. Dafür kombinieren wir die
beiden bereits Verwendeten ansätze. Wir fassen wieder die daten mithilfe
von group_by(Year) anhand der Jahre Zusammen. Die erhaltene
Tabelle fassen wir wieder mit dplyr::summarize(gr_sum =
sum(Global_Sales)) zusammen. Diesmal nutzen wir jedoch eine
kombination aus sum(Global_Sales) und n(). Wir
addieren die Spalte Global_Sales, teilen dies durch die Anzahl
der Einträge und speichern den Wert in die Spalte gamesales
(gamesales = sum(Global_Sales)/n()). Danach filtern wir die
Daten erneut und speichern sie als data.frame in grouped ab.
Diesmal selektieren wie die Einträge der Spalte Jahr sowie
gamesales und speichern sie in der Variable filtered
ab. Zuletzt erstellen wir erneut die Variablen ax und
ay und verwenden plot_ly() um mithilfe der type =
‘scatter’ und mode = ‘lines’ Parameter ein Liniendiagramm
zu erstellen sowie die layout() funktion um einen titel zu
erstellen und mithilfe unsere beiden Variablen ax und ay die Achsen zu
beschriften.
grouped <- vgsales %>%
group_by(Year) %>%
dplyr::summarize(gamesales = sum(Global_Sales)/n()) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
filtered <- grouped %>% select(Year,gamesales)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "Verkäufe pro Spiel"
)
filtered %>%
plot_ly(x = ~Year, y = ~gamesales, type = 'scatter', mode = 'lines', fill = 'tozeroy' ,colors = myPalette) %>%
layout(title="Videospielverkäufe pro Spiel von 1980-2016",
xaxis = ax,
yaxis = ay
)
NA
Sahen sich die beiden Diagramme für Anzahl und Verkaufszahlen noch
recht ähnlich stellt sich hier ein deutlich unterschiedlicher Verlauf
da. Ist der Wert zwischen 1980 (1.26) und 1983 (0.98) noch relativ
gering steigt dieser Massiv für die Jahre 1984(3.59) und 1985(3.85)
bevor er 1986(1.76) und 1987(1.35) wieder absinkt. Genauso schnell wie
der wert abgesunken ist steigt er allerdings auch wieder auf 3.14(1988)
bevor er 1989 den Höchststand mit 4.32 erreicht. Danach sinkt der wieder
ab um sich nach einem kurzen ausschlag 1992 in den Jahren bis 2014 auf
einen relativ stetigen Wert Zwischen 0.5 und 0.7 einzupendeln erst 2015
und 2016 sinkt dieser unter 0.5. Diese Extremen ausschläge in den
Früheren Jahren lassen sich mit der Geringen anzahl der Spiele erklären.
Einzelne gute laufende Spiele machen hier noch einen Großteil des Markts
aus wohingegen sich neuere spiele, sowohl gegen eine Großzahl von
bereits etablierten Spiele als auch eine große Anzahl neuer Releases,
durchsetzen müssen.
Platform Verkaufszahlen im laufe der Jahre
Nachdem wir uns die Platform verteilung angeschaut haben stellt sich
die Frage ob es im laufe der Jahre unterschiede in den Verkäufen
gibt.
Um uns dies anzuschaun verwenden wir eine neue art der Grafik die wir
bisher noch nicht verwendet haben. Zum erstellen der Grafik gruppieren
wir zuerst wieder unsere Daten und addieren die werte der Sales pro Jahr
und Platform auf. ZUsätzlich zum Filter der ungültigen Jahre filter wir
allerdings alle Summen mit weniger als 60 mio in Sales. Dies ist um eine
Überladung des Diagramms zu verhindern führt aber zu anderen Problemen. Neu in der erstellung dieses
Diagramms sind auch die befehle arrange() und slice().
Arrange sortiert die Tabelle anhand der gegebenen Spalte in unserem fall
ist das die Summe der Globalen verkäufe. Slice entfernt alle Spalten bis
auf jene, welche wir verwenden wollen. Neu bei der Diagamm erstellung
sind hier die Parameter mode = ‘none’ sowie stackgroup =
‘one’ welche die hier zu sehende Grafik erzeugen.
grouped <- vgsales %>%
group_by(Year, Platform) %>%
dplyr::summarize(gr_sum = sum(Global_Sales)) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>% filter(gr_sum>60)%>%
as.data.frame()
`summarise()` has grouped output by 'Year'. You can override using the `.groups` argument.
grouped <- grouped %>%arrange(desc(gr_sum)) %>%
group_by(Year, Platform) %>%
slice(1:3)
filtered <- grouped %>% select(Year,Platform,gr_sum)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "verkäufe pro Platform (in mio)"
)
filtered %>%
plot_ly(x = ~Year, y = ~gr_sum, type = 'scatter', mode = 'none', stackgroup = 'one',color = ~Platform ,colors = myPalette)%>%
layout(title="Verkäufe pro Platform von 1980-2016",
xaxis = ax,
yaxis = ay
)
NA
Im ersten Moment ist die Grafik sehr verwirrend aber dröseln wir das
ganze einmal genauer auf. Zuerst einmal fällt auf, dass die Jahre
1980-1988 sowie 1990-1005 und 2016 fehlen. Dies liegt an den oben
gewählten Filtern und den in den Jahren pro Plattform gemessen zu
geringen Verkaufszahlen. Zwischen den Jahren 1996 und 2000 ist hier nur
die Playstation, welche 1994 veröffentlicht wurde zu erkennen. Im Jahre
2000 wird diese dann von der Playstation 2, welche am 04.03.2000 releast
wurde abgelöst. Auch der Gameboy Advanced hier in den Jahren 2000-2003
sowie 2004 zu erkennen, obwohl dieser Global erst Mitte des Jahres 2001
releast wurde.2004 wird die Playstation 2 dann von der Xbox, welche am
22.02.2002 erstmals veröffentlich wurde, kurzzeitig abgelöst bevor die
Wii(02.12.2006) mit nur einem Verkaufsmonat des Jahres 2006 die Führung
übernimmt. Auch die Verkaufszahlen des Nintendo DS (02.12.2004) sind in
den Jahren 2005-2010 gut erkennbar. Die XboX360 (10.12.2005) übernimmt
ab 2007 den ersten Platz der Rangliste und wird erst 2014 von der
PS4(15.11.2013) abgelöst.
Allgemein ist hier ein Trend erkennbar. Meist verkaufen Platformen
wie zu erwarten einige Zeit nach Release die meisten Spiele.
Erstaunlicherweise ist dies jedoch nicht kurz nach Release sondern z.T.
erst einige Jahre später. Interessant währe hier eine detailliertere
analyse aber weiteres dazu hier.
Publisher Vergleich
Nachdem wir uns nun eine Übersicht über die Platformen gemacht haben
wäre es doch interessant zu wissen ob sich neben bestimmten Platformen
auch bestimmte Entwickler/Publisher häufen. Anzunehmen ist hierbei das
Namenhafte Publisher wie EA und Nintendo die Liste anführen. Hierzu
verwenden wir wiederum Paretodiagramme. Eine genauere erklärung zur
erstellung ebenjener gibt es hier.
Einzige neuerung in diesem abschnitt ist das Kürzen der Namen um die
Begriffe “Entertainment”, “Interactive”, “Game”, “Games” und “Studios”
da dies die Namen nur unnötig verlängert. Um dies zu erreichen mutzen
wir die Funktion str_remove_all() auf die Spalte Publisher.
Publisher
nach Anzahl
grouped <- vgsales %>%
group_by(Publisher) %>%
summarize(Anzahl =n()) %>%
filter(Anzahl>100) %>% filter(Publisher!="Unknown")
PublisherSales <- vgsales %>%
group_by(Publisher) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
) %>% filter(Global_Sales>300)
grouped <- grouped %>% filter(Publisher %in% PublisherSales$Publisher)
ordered <- grouped[order(grouped$Anzahl), decreasing = FALSE]
ordered$Publisher <-str_remove_all(ordered$Publisher, "Entertainment")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Interactive")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Studios")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Games")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Game")
ordered$Publisher <- as_factor(ordered$Publisher)
ax <- list(
title = "Publisher"
)
ay <- list(
title = "Anzahl"
)
ordered%>%
plot_ly() %>%
add_bars(x=~fct_reorder(Publisher,Anzahl, .desc="true"),
y=~Anzahl,
name="Spiele Anzahl pro Publisher"
,colors = myPalette) %>%
layout(title="Spiele Anzahl pro Publisher",
xaxis = ax,
yaxis = ay
)
Betrachten wir zuerst einmal die Anzahl der Spielereleases. Wenig
überaschend ist hier EA (1351), mit jährlich veröffentlichenden
namenhaften Spielen wie FIFA und Madden NFL sowie anderen bekannten
Reihen wie Need for Speed, Battlefield oder Sims, anführer der Liste. An
zweiter stelle befindet sich Activision (975) die unter anderem Spiele
wie World of Warcraft, die Diablo reihe sowie Candy Crush entwickelten.
Zum Zeitpunkt der Erstellung dieser Arbeit sind diese noch ein eigener
Konzern werden allerdings vorausichtlich 2023 Teil von Microsoft. Darauf
folgen in kurzen abständen Ubisoft (921), welche für Assasins Creed,
Rainbox six oder Anno bekannt sind, sowie THQ mit 715 (Gothic,
Darksiders, TitanQuest). Auch Nintendo (703) mit Mario, Pokemon und
Zelda sowie Sony (638), bekannt durch die Gran Tourismo und Uncharted
Reihe sowie The last of Us, sind nicht weit abgeschlagen. Den letzten
platz der Top Publisher belegt Take Two, welche für GTA, Borderlands und
Civilization bekannt sind, mit 413.
nach Verkaufszahlen
grouped <- vgsales %>%
group_by(Publisher) %>%
summarize(Anzahl =n(),sum(Global_Sales)) %>%
filter(Anzahl>100) %>%
rename(
Global_Sales = "sum(Global_Sales)"
)
PublisherSales <- vgsales %>%
group_by(Publisher) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
) %>% filter(Global_Sales>300)
grouped <- grouped %>% filter(Publisher %in% PublisherSales$Publisher)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ordered$Publisher <-str_remove_all(ordered$Publisher, "Entertainment")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Interactive")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Studios")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Games")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Game")
ordered$Publisher <- as_factor(ordered$Publisher)
ax <- list(
title = "Publisher"
)
ay <- list(
title = "Verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_bars(x=~fct_reorder(Publisher,Global_Sales, .desc="true"),
y=~Global_Sales,
name="Verkaufszahlen pro Publisher"
,colors = myPalette) %>%
layout(title="Verkaufszahlen pro Publisher",
xaxis = ax,
yaxis = ay
)
Beim Betrachten der Verkaufszahlen fällt hier direkt die diskrepanz
zwischen Anzahl der Spielereleases und Anzahl der Spieleverkäufe auf. Im
gegensatz zu der Anzahl der Spiele (bei dem Nintendo nur auf platz 6
Sitz) dominiert Nintendo(1.786 mrd) in Sales. EA (1.1 mrd), welche noch
mit Abstand die meisten spielreleases hatten sind in den Verkäufen nur
noch mit deutlichem Abstand auf Platz 2. Auch die anderen Plätze
verändern sich leicht die Unterschiede sind hier jedoch deutlich
geringer als bei Nintendo und EA. Interessant wäre hierzu vielleicht
noch ein direkter vergleich zwischen Anzahl und Sales aber genaueres
dazu im Fazit
Publisher Ranking nach Region
Nachdem wir uns einen Allgemeinen Überblick über die Publisher
gemacht haben betrachten wir die Regionalen unterschiede in den
Verkaufszahlen. Hierzu verwenden wir erneut die Bereits bekannten
Shemata der Pareto- und Kreisdiagramm kombo. Einen Refresher
für die Erstellung ebenjener Diagramme gibt es via den Entsprechenden
Links.
Ranking nach Region
Balkendiagramme
Europa
grouped <- vgsales %>%
group_by(Publisher) %>%
summarize(Anzahl =n(),sum(EU_Sales)) %>%
filter(Anzahl>100) %>%
rename(
Global_Sales = "sum(EU_Sales)"
)
PublisherSales <- vgsales %>%
group_by(Publisher) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
) %>% filter(Global_Sales>300)
grouped <- grouped %>% filter(Publisher %in% PublisherSales$Publisher)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ordered$Publisher <-str_remove_all(ordered$Publisher, "Entertainment")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Interactive")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Studios")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Games")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Game")
ordered$Publisher <- as_factor(ordered$Publisher)
ax <- list(
title = "Publisher"
)
ay <- list(
title = "EU verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_bars(x=~fct_reorder(Publisher,Global_Sales, .desc="true"),
y=~Global_Sales,
name="EU Verkaufszahlen pro Publisher"
,colors = myPalette) %>%
layout(title="EU Verkaufszahlen pro Publisher",
xaxis = ax,
yaxis = ay
)
Im vergleich zu den Globalen Verkaufszahlen fällt hier auf das EA
(371.27 mio) deutlich dichter hinter Nintendo(418.74) auf dem Zweiten
Platz ist. Der Abstand zwischen EA und Activision (215.53) ist
dementsprechend auch deutlich größer. Die restlichen werte unterscheiden
sich aber kaum.
Nord Amerika
grouped <- vgsales %>%
group_by(Publisher) %>%
summarize(Anzahl =n(),sum(NA_Sales)) %>%
filter(Anzahl>100) %>%
rename(
Global_Sales = "sum(NA_Sales)"
)
PublisherSales <- vgsales %>%
group_by(Publisher) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
) %>% filter(Global_Sales>300)
grouped <- grouped %>% filter(Publisher %in% PublisherSales$Publisher)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ordered$Publisher <-str_remove_all(ordered$Publisher, "Entertainment")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Interactive")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Studios")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Games")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Game")
ordered$Publisher <- as_factor(ordered$Publisher)
ax <- list(
title = "Publisher"
)
ay <- list(
title = "NA verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_bars(x=~fct_reorder(Publisher,Global_Sales, .desc="true"),
y=~Global_Sales,
name="NA Verkaufszahlen pro Publisher"
,colors = myPalette) %>%
layout(title="NA Verkaufszahlen pro Publisher",
xaxis = ax,
yaxis = ay
)
Auch in Nord Amerika kann EA(595.07) leicht größere Verkaufszahlen im
vergleich mit Nintendo (816.87) als noch Global verbuchen. Im gegensatz
zu Europa scheint jedoch Activision (429.7) in Amerika deutlich
beliebter zu sein. Die weiteren Publisher sind auch weiterhin nicht
Relevant.
Japan
grouped <- vgsales %>%
group_by(Publisher) %>%
summarize(Anzahl =n(),sum(JP_Sales)) %>%
filter(Anzahl>100) %>%
rename(
Global_Sales = "sum(JP_Sales)"
)
PublisherSales <- vgsales %>%
group_by(Publisher) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
) %>% filter(Global_Sales>300)
grouped <- grouped %>% filter(Publisher %in% PublisherSales$Publisher)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ordered$Publisher <-str_remove_all(ordered$Publisher, "Entertainment")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Interactive")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Studios")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Games")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Game")
ordered$Publisher <- as_factor(ordered$Publisher)
ax <- list(
title = "Publisher"
)
ay <- list(
title = "JP verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_bars(x=~fct_reorder(Publisher,Global_Sales, .desc="true"),
y=~Global_Sales,
name="JP Verkaufszahlen pro Publisher"
,colors = myPalette) %>%
layout(title="JP Verkaufszahlen pro Publisher",
xaxis = ax,
yaxis = ay
)
Japan Zeigt hier wohl den Deutlichsten unterschied auf. Nintendo
(455.42) Dominiert hier die Verkaufszahlen mit der mehr als 6 fachen
menge an verkäufen als Sony (74.1) welche sich den 2. Platz sichern. Die
anderen Publisher sind alle fast gleich irrelevant in Japan.
Kreisdiagramme
Europa
grouped <- vgsales %>%
group_by(Publisher) %>%
summarize(Anzahl =n(),sum(EU_Sales)) %>%
filter(Anzahl>100) %>%
rename(
Global_Sales = "sum(EU_Sales)"
)
PublisherSales <- vgsales %>%
group_by(Publisher) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
) %>% filter(Global_Sales>300)
grouped <- grouped %>% filter(Publisher %in% PublisherSales$Publisher)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ordered$Publisher <-str_remove_all(ordered$Publisher, "Entertainment")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Interactive")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Studios")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Games")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Game")
ordered$Publisher <- as_factor(ordered$Publisher)
ax <- list(
title = "Publisher"
)
ay <- list(
title = "EU verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_pie(values =~Global_Sales,labels=~Publisher,
name="EU Verkaufszahlen pro Publisher"
,colors = myPalette) %>%
layout(title="EU Verkaufszahlen pro Publisher",
xaxis = ax,
yaxis = ay
)
Im vergleich zu den Globalen Verkaufszahlen fällt hier auf das EA
(23.7%) deutlich dichter hinter Nintendo(26.7%) auf dem Zweiten Platz
ist. Der Abstand zwischen EA und Activision (13.7%) ist dementsprechend
auch deutlich größer. Die restlichen werte unterscheiden sich kaum.
Nord-Amerika
grouped <- vgsales %>%
group_by(Publisher) %>%
summarize(Anzahl =n(),sum(NA_Sales)) %>%
filter(Anzahl>100) %>%
rename(
Global_Sales = "sum(NA_Sales)"
)
PublisherSales <- vgsales %>%
group_by(Publisher) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
) %>% filter(Global_Sales>300)
grouped <- grouped %>% filter(Publisher %in% PublisherSales$Publisher)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ordered$Publisher <-str_remove_all(ordered$Publisher, "Entertainment")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Interactive")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Studios")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Games")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Game")
ordered$Publisher <- as_factor(ordered$Publisher)
ax <- list(
title = "Publisher"
)
ay <- list(
title = "NA verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_pie(values =~Global_Sales,labels=~Publisher,textinfo='label+percent',
name="NA Verkaufszahlen pro Publisher"
,colors = myPalette) %>%
layout(title="NA Verkaufszahlen pro Publisher",
xaxis = ax,
yaxis = ay
)
Auch in Nord Amerika kann EA(21.3%) leicht größere Verkaufszahlen im
vergleich mit Nintendo (29.3%) als noch Global verbuchen diese sind
jedoch geringer als noch in Europa. Im gegensatz zu Europa scheint
jedoch Activision (15.4%) in Amerika deutlich beliebter zu sein. Die
weiteren Publisher sind auch weiterhin nicht Relevant.
Japan
grouped <- vgsales %>%
group_by(Publisher) %>%
summarize(Anzahl =n(),sum(JP_Sales)) %>%
filter(Anzahl>100) %>%
rename(
Global_Sales = "sum(JP_Sales)"
)
PublisherSales <- vgsales %>%
group_by(Publisher) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
) %>% filter(Global_Sales>300)
grouped <- grouped %>% filter(Publisher %in% PublisherSales$Publisher)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ordered$Publisher <-str_remove_all(ordered$Publisher, "Entertainment")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Interactive")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Studios")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Games")
ordered$Publisher <-str_remove_all(ordered$Publisher, "Game")
ordered$Publisher <- as_factor(ordered$Publisher)
ax <- list(
title = "Publisher"
)
ay <- list(
title = "JP verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_pie(values =~Global_Sales,labels=~Publisher,
name="JP Verkaufszahlen pro Publisher"
,colors = myPalette) %>%
layout(title="JP Verkaufszahlen pro Publisher",
xaxis = ax,
yaxis = ay
)
Japan Zeigt hier wohl den Deutlichsten unterschied auf. Nintendo
(80.1%) Dominiert hier die Verkaufszahlen mit der mehr als 6 fachen
menge an verkäufen als Sony (13%) welche sich den 2. Platz sichern. Die
anderen Publisher sind mit weniger als 2.5% alle fast gleich irrelevant
in Japan.
Zwischen EU und US lassen sich hier kaum Unterschiede feststellen in
Japan hingegen ist eine deutliche verschiebung zu erkennen. Japanische
Publisher führen hierbei die Liste an und drängen andere große
unternehmen von den Top spots. Dementsprechend können wir schlussfolgern
das manche Regionen, vorallem Japan welches die kleinste Region ist,
deutliche vorlieben in spielen bestimmter Publisher haben, welche von
der Globalen norm Abweichen. Eine Genauere Analyse von Europa und Nord
Amerika durch unterteilung in Länder/Staaten währe hier vermutlich
deutlich interessanter wird von den Daten jedoch leider nicht
angeboten.
Genreverteilung der Videospiele nach Anzahl
Da wir uns nu klar geworden sind, dass es bestimmte Publisher gibt,
die beliebter sind als andere wäre es interessant herauszufinden ob
bestimmte Spiele Genres beliebter sind als andere. Hierzu vergleichen
wir zuerst einmal die Genres nach anzahl der Spielereleases und
verwenden erneut ein Pareto- und Kreisdiagramm. Anzumerken ist
hierbei jedoch das Spiele meist mehr als einem Genre angehören in diesem
Datensatz ist jedoch immer nur eins angegeben.
Genre nach Anzahl
Balkendiagramm
grouped <- vgsales %>%
group_by(Genre) %>%
summarize(Anzahl =n())
grouped$Anzahl<-as_vector(grouped$Anzahl)
ordered <- grouped[order(grouped$Anzahl), decreasing = FALSE]
ordered$Genre <- as_factor(ordered$Genre)
ax <- list(
title = "Genre"
)
ay <- list(
title = "Anzahl"
)
ordered%>%
plot_ly() %>%
add_bars(x=~fct_reorder(Genre,Anzahl, .desc="true"),
y=~Anzahl,
name="Videospielanzahl nach Genre"
,colors = myPalette) %>%
layout(title="Videospielanzahl nach Genre",
xaxis = ax,
yaxis = ay
)
NA
Der Anführer der Liste ist mit deutlichem Abstand Action
(GTA,Bloodborne) mit 3316. Auf dem Zweiten platz findet sich Sports
(2346) mit reihen wie FIFA und NBA2k. Den dritten Platz belegt ein Genre
das aus vielen verschiedenen Genren besteht die in dieser Liste nicht
aufgeführt werden mit 1739. Misc beinhaltet spiele wie Just Dance
(Musik/Rhythmus) oder Minecraft ein Sandbox Survival game. Danach kommen
mit geringerem Abstand der Reihe nach Role-Playing (Witcher, The Elder
Scrolls) mit 1488, Shooter (Call of Duty, Doom) mit 1310, Adventure (God
of War, Life is Strange) mit 1286 und Racing (Gran Tourismo, Forza) mit
1249. Danach folgen mit einem größeren Abstand Platform (Super Mario,
LittleBigPlanet) mit 886, Simulation (Sims, Microsoft Flight Simulator)
mit 867 sowie Fighting (Tekken, Super Smash Bros) mit 884. Zu guter
letzt fehlen noch Strategy (Age of Empires, Civilisation) mit 681 sowie
Puzzle (Portal,Tetris) mit 582.
Kreisdiagramm
grouped <- vgsales %>%
group_by(Genre) %>%
summarize(Anzahl =n())
grouped$Anzahl<-as_vector(grouped$Anzahl)
ordered <- grouped[order(grouped$Anzahl), decreasing = FALSE]
ordered$Genre <- as_factor(ordered$Genre)
ax <- list(
title = "Genre"
)
ay <- list(
title = "Anzahl"
)
ordered%>%
plot_ly() %>%
add_pie(values =~Anzahl,labels=~Genre,
name="Videospielanzahl nach Genre"
,colors = myPalette) %>%
layout(title="Videospielanzahl nach Genre",
xaxis = ax,
yaxis = ay
)
Der Anführer der Liste ist mit deutlichem Abstand Action
(GTA,Bloodborne) mit 20%. Auf dem Zweiten platz findet sich Sports
(14.1%) mit reihen wie FIFA und NBA2k. Den dritten Platz belegt ein
Genre das aus vielen verschiedenen Genren besteht die in dieser Liste
nicht aufgeführt werden mit 10.5%. Misc beinhaltet spiele wie Just Dance
(Musik/Rhythmus) oder Minecraft ein Sandbox Survival game. Danach kommen
mit geringerem Abstand der Reihe nach Role-Playing (Witcher, The Elder
Scrolls) mit 8.96%, Shooter (Call of Duty, Doom) mit 7.89%, Adventure
(God of War, Life is Strange) mit 7.75% und Racing (Gran Tourismo,
Forza) mit 7.53%. Danach folgen mit einem größeren Abstand Platform
(Super Mario, LittleBigPlanet) mit 5.34%, Simulation (Sims, Microsoft
Flight Simulator) mit 5.22% sowie Fighting (Tekken, Super Smash Bros)
mit 5.11%. Zu guter letzt fehlen noch Strategy (Age of Empires,
Civilisation) mit 4.1% sowie Puzzle (Portal,Tetris) mit 3.51%.
Auffällig hierbei ist das die Größten vier Genres 53.56% der
Spielereleases ausmachen. Dies ist ansich nicht weiter Verwunderlich. In
der Spieleindustrie bzw allgemein, ist es ein gerne genutztes konzept
Funktionierende dinge zu übernehmen. Dies ist vorallem auffällig bei
Spielen, welche ganze Genres prägen. Sei es Minecraft für die Survival
Games (DayZ, Rust), World of Warcraft für die MMORPG’s (Final Fantasy
14, Guild Wars 2) oder die Warcraft 3 mod Dota welche das MOBA genre
(League of Legends, Dota 2) nach sich gezogen hat.
Genreverteilung der Videospiele nach Verkaufszahlen
Schauen wir uns nun jedoch an ob die Verkaufszahlen die gleichen
häufungen aufzeigen und verwenden wieder ein Pareto- und Kreisdiagramm. Es gilt weiterhin die
obengenannte Problematik der Genrenotation des Datensatzes.
Verkaufszahlen
Balkendiagramm
grouped <- vgsales %>%
group_by(Genre) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ax <- list(
title = "Genre"
)
ay <- list(
title = "Verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_bars(x=~fct_reorder(Genre,Global_Sales, .desc="true"),
y=~Global_Sales,
name="Verkaufszahlen nach Genre"
,colors = myPalette) %>%
layout(title="Verkaufszahlen nach Genre",
xaxis = ax,
yaxis = ay
)
NA
Auf Platz 1 und 2 der Liste befinden sich weiterhin Action (1.751
mrd) und Spots (1.33 mrd). Platz 3 belegt hier jedoch nicht Misc welches
mit 809.96 mio auf platz 6 abgerutscht ist sondern Shooter (1.037 mrd).
Platz 4 wird weiterhin von Role-Playing (927.37 mio) belegt. Auch
Platform (831.37) verkaufen sich deutlich besser und sichern sich Platz
5. Die restlichen Genres unterscheiden sich Kaum in Anzahl und
Verkaufszahlen.
Kreisdiagramm
grouped <- vgsales %>%
group_by(Genre) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ax <- list(
title = "Genre"
)
ay <- list(
title = "Verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_pie(values =~Global_Sales,labels=~Genre,
name="Verkaufszahlen nach Genre"
,colors = myPalette) %>%
layout(title="Verkaufszahlen nach Genre",
xaxis = ax,
yaxis = ay
)
Auf Platz 1 und 2 der Liste befinden sich weiterhin Action (19.6%)
und Spots (14.9%). Platz 3 belegt hier jedoch nicht Misc welches mit
9.08% auf platz 6 abgerutscht ist sondern Shooter (11.6%). Platz 4 wird
weiterhin von Role-Playing (10.4%) belegt. Auch Platform (9.32%)
verkaufen sich deutlich besser und sichern sich Platz 5. Die restlichen
Genres unterscheiden sich Kaum in Anzahl und Verkaufszahlen.
Beim Betrachten fällt hier auf, dass sich einige Genres deutlich
besser verkaufen als andere. Vorallem Shooter und Platform spiele sind
hier die Kassenschlager wenn man die Verkaufszahlen mit Anzahl der
Spiele vergleicht. Die großen Genres Action und Sports sind jedoch
sowohl in verkaufszahlen als auch Anzahl der Spiele unangefochten auf
platz 1 und 2.
Regionale Unterschiede der Genres
Nachdem wir vorhin bei den Platformen deutliche Regionale
Unterschiede feststellen konnten stellt sich bei den Genres die gleiche
Frage und dementsprechend auch wieder der gleiche Lösungsansatz mit Pareto- und Kreisdiagrammen.
Verkäufe pro Genre
Balkendiagramme
Europa
grouped <- vgsales %>%
group_by(Genre) %>%
summarize(sum(EU_Sales)) %>%
rename(
Global_Sales = "sum(EU_Sales)"
)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ax <- list(
title = "Genre"
)
ay <- list(
title = "Verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_bars(x=~fct_reorder(Genre,Global_Sales, .desc="true"),
y=~Global_Sales,
name="Verkaufszahlen nach Genre (EU)"
,colors = myPalette) %>%
layout(title="Verkaufszahlen nach Genre (EU)",
xaxis = ax,
yaxis = ay
)
Europa sieht wie bereits in der Platformanalyse festgestellt dem
Globalen Genrevergleich recht ähnlich. Action (525 mio) führt weiterhin
vor Sports(376.85 mio) und Shootern (313.27 mio). Auf platz 4 ist dann
der erste Unterschied feststellbar. Anstatt Role-Playing (188.06 mio)
welches auf Platz 7 abgerutscht ist befindet sich hier Racing (238.39)
welche den Platz tauschen. Auch Platz 5 Misc (215.98 mio) und Platz 6
Platform (201.63 mio) sind in Europa vertauscht. Allgemein scheint hier
auf den hinteren Genreplätzen eine verschiebung feststellbar zu sein
denn obwohl das verhältnis der Genres gleich bleibt sind zusätzlich
sowohl Simulation (113.38 mio) und Fighting (101.32 mio) als auch
Adventure (63.13 mio) und Puzzle (50.78 mio) vertauscht. Von den
hinteren Plätzen bleibt somit einzig Strategy (45.34 mio) auf seinem
vorherigen letzten platz.
Nord-Amerika
grouped <- vgsales %>%
group_by(Genre) %>%
summarize(sum(NA_Sales)) %>%
rename(
Global_Sales = "sum(NA_Sales)"
)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ax <- list(
title = "Genre"
)
ay <- list(
title = "Verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_bars(x=~fct_reorder(Genre,Global_Sales, .desc="true"),
y=~Global_Sales,
name="Verkaufszahlen nach Genre (NA)"
,colors = myPalette) %>%
layout(title="Verkaufszahlen nach Genre (NA)",
xaxis = ax,
yaxis = ay
)
Auch in Nord-Amerika ist eine Verschiebung der Genres festzustellen.
Die Top 3 sind weiterhin von Action (877.83 mio), Sports (683.35 mio)
und Shooter (582.6 mio) belegt. Im gegensatz zu Europa sind hier
allerdings nur Platz 4 Platform (447.05 mio), Platz 5 Misc (410.24 mio)
sowie Platz 6 Racing (359.42) und Platz 7 Role-Playing (327.28 mio)
vertauscht. Platz 8 bis 12 sind wie die globalen Referenzwerte
angeordnet der einzige Unterschied zwische Global und Nord-Amerika ist
somit die verschiebung von Role-Playing auf Platz 7.
Japan
grouped <- vgsales %>%
group_by(Genre) %>%
summarize(sum(JP_Sales)) %>%
rename(
Global_Sales = "sum(JP_Sales)"
)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ax <- list(
title = "Genre"
)
ay <- list(
title = "Verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_bars(x=~fct_reorder(Genre,Global_Sales, .desc="true"),
y=~Global_Sales,
name="Verkaufszahlen nach Genre (JP)" ,colors = myPalette) %>%
layout(title="Verkaufszahlen nach Genre (JP)",
xaxis = ax,
yaxis = ay
)
NA
In Japan befindet sich Role-Playing (352.31 mio) mit großem Abstand
auf Platz 1 noch vor de sonstigen Platzhirschen Action (159.95 mio) und
Sports (135.37 mio). Die ehemalige top 3 Shooter (38.28 mio) fällt in
Japan auf den letzten platz ab und wird von Platform (130.77 mio)
ersetzt. Misc (107.76 mio) kann sich weiterhin im mittelfeld halten
wohingegen Fighting (87.35 mio) und Simulation (63.7 mio) einige Plätze
gut machen können und nun auf Platz 6 und 7 vorrücken. Auch Puzzle Games
(57.31 mio) erfreuen sich einer höheren beliebtheit als noch Global
wohingegen Racing (56.69 mio) einen deutlichen Verlust hinnehmen muss.
Adventure (52.07 mio) und Strategy (49.46 mio) bleiben jedoch weiterhin
eine der Unbeliebtesten Genres.
Kreisdiagramme
Europa
grouped <- vgsales %>%
group_by(Genre) %>%
summarize(sum(EU_Sales)) %>%
rename(
Global_Sales = "sum(EU_Sales)"
)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ax <- list(
title = "Genre"
)
ay <- list(
title = "Verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_pie(values =~Global_Sales,labels=~Genre,
name="Verkaufszahlen nach Genre (EU)" ,colors = myPalette) %>%
layout(title="Verkaufszahlen nach Genre (EU)",
xaxis = ax,
yaxis = ay
)
Europa sieht wie bereits in der Platformanalyse festgestellt dem
Globalen Genrevergleich recht ähnlich. Action (21.6%) führt weiterhin
vor Sports(15.5%) und Shootern (12.9%). Auf platz 4 ist dann der erste
Unterschied feststellbar. Anstatt Role-Playing (7.73%) welches auf Platz
7 abgerutscht ist befindet sich hier Racing (9.79%) welche den Platz
tauschen. Auch Platz 5 Misc (8.87%) und Platz 6 Platform (8.28%) sind in
Europa vertauscht. Allgemein scheint hier auf den hinteren Genreplätzen
eine verschiebung feststellbar zu sein denn obwohl das verhältnis der
Genres gleich bleibt sind zusätzlich sowohl Simulation (4.66%) und
Fighting (4.16%) als auch Adventure (2.63%) und Puzzle (2.09%)
vertauscht. Von den hinteren Plätzen bleibt somit einzig Strategy
(1.86%) auf seinem vorherigen letzten platz.
Nord-Amerika
grouped <- vgsales %>%
group_by(Genre) %>%
summarize(sum(NA_Sales)) %>%
rename(
Global_Sales = "sum(NA_Sales)"
)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ax <- list(
title = "Genre"
)
ay <- list(
title = "Verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_pie(values =~Global_Sales,labels=~Genre,
name="Verkaufszahlen nach Genre (NA)",colors = myPalette) %>%
layout(title="Verkaufszahlen nach Genre (NA)",
xaxis = ax,
yaxis = ay
)
Auch in Nord-Amerika ist eine Verschiebung der Genres festzustellen.
Die Top 3 sind weiterhin von Action (20%), Sports (15.6%) und Shooter
(13.3%) belegt. Im gegensatz zu Europa sind hier allerdings nur Platz 4
Platform (10.2%), Platz 5 Misc (9.34%) sowie Platz 6 Racing (8.18%) und
Platz 7 Role-Playing (7.45%) vertauscht. Platz 8 bis 12 sind wie die
globalen Referenzwerte angeordnet der einzige Unterschied zwische Global
und Nord-Amerika ist somit die verschiebung von Role-Playing auf Platz
7.
Japan
grouped <- vgsales %>%
group_by(Genre) %>%
summarize(sum(JP_Sales)) %>%
rename(
Global_Sales = "sum(JP_Sales)"
)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ordered <- grouped[order(grouped$Global_Sales), decreasing = FALSE]
ax <- list(
title = "Genre"
)
ay <- list(
title = "Verkäufe (in mio)"
)
ordered%>%
plot_ly() %>%
add_pie(values =~Global_Sales,labels=~Genre,
name="Verkaufszahlen nach Genre (JP)" ,colors = myPalette) %>%
layout(title="Verkaufszahlen nach Genre (JP)",
xaxis = ax,
yaxis = ay
)
In Japan befindet sich Role-Playing (27.3%) mit großem Abstand auf
Platz 1 noch vor de sonstigen Platzhirschen Action (12.4%) und Sports
(10.5%). Die ehemalige top 3 Shooter (2.97%) fällt in Japan auf den
letzten platz ab und wird von Platform (10.1%) ersetzt. Misc (8.35%)
kann sich weiterhin im mittelfeld halten wohingegen Fighting (6.77%) und
Simulation (4.93%) einige Plätze gut machen können und nun auf Platz 6
und 7 vorrücken. Auch Puzzle Games (4.44%) erfreuen sich einer höheren
beliebtheit als noch Global wohingegen Racing (4.39%) einen deutlichen
Verlust hinnehmen muss. Adventure (4.03%) und Strategy (3.83%) bleiben
jedoch weiterhin eine der Unbeliebtesten Genres.
Zu erkennen ist hier erneut das Amerika und Euopa recht ähnlich
interessen haben und nur auf den mittleren und hinteren plätzen
unterschiede aufweisen. Nord-Amerika ist als der größte Markt wie zu
erwartend am nächsten an den Globalen Referenzdaten wohingegen Japan ein
gänzlich anderes Genreshema erkennen lässt. In Japan dominiert
Role-Playing welches sich in Europa und Amerika nur auf platz 7 befindet
welches durch die Japanische Kultur geprägt auch sinn ergibt.
Genreentwicklung im laufe der Jahre nach anzahl
Nachdem wir uns nun Über die Genreverteilung Global und in den
einzelnen Regionen ein Bild gemacht haben wäre es interessant
anzuschauen wie sich die Genres im Laufe der Jahre entwickelt haben und
ob sich ein Trend bei Gewissen Genres erkennen lässt. Als erstes
Betrachten wir reine Anzahl der Spielereleases und später die verkaufszahlen. Hierzu
verwenden wir verschiedene Lineplots die sich in der Datenvorbereitung
nicht großartig von den Pareto- und Kreisdiagrammen unterscheidet. Die
unterschiede in der Diagramm erstellung werde ich jedoch im Folgenden
aufzeigen.
Anzahl der Spiele pro Genre pro Jahr
Lines
Die erstellung des Lines Diagrammes ist wohl die simpelste. Wir
verwenden unsere vorgefiltertes data.frame filtered und
übergeben dies an die plot_ly() funktion. Danach nutzen wir
add_lines um ein Liniendiagramm zu erstellen und setzen die
Parameter. Der X-Wert ist das Year, der Y-Wert die
Anzahl. Als color wählen wir das Genre und unsere
Farbtabelle übergeben wir an die funktion via colors=.
grouped <- vgsales %>%
group_by(Year, Genre) %>%
dplyr::summarize(Anzahl =n()) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
`summarise()` has grouped output by 'Year'. You can override using the `.groups` argument.
filtered <- grouped %>% select(Year,Genre,Anzahl)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "Anzahl"
)
filtered %>%
plot_ly() %>%
add_lines(x=~Year,
y=~Anzahl, color=~Genre,colors = myPalette) %>%
layout(title="Anzahl der Spielereleases von 1980-2016",
xaxis = ax,
yaxis = ay
)
NA
Im ersten moment ist dieses Diagramm recht unübersichtlich doch bei
genaueren Betrachtung kann ein aufmerksamer Betrachter bereits einige
Dinge erkennen. Zum einen sehen wir das zwischen 1993 und 2003
tatsächlich Sports das meist verkaufte Genre war bevor es von Action
abgelöst wurde. Misc games erfreuten sich zwischen 2005 und 2011 großer
beliebtheit bevor diese wieder in der Versenkung verschwanden. Auch
Adventure games waren zwischen 2007 und 2010 am beliebtesten.
Filled Lines
Die Erstellung des Filled Lines Diagrammes unterscheides sich etwas
von dem einfach Lines-Plot. Anstatt der add_Lines funktion
übergeben wir hier direkt die Parameter mit an plot_ly(). X ist
weiterhin das Jahr, Y die Anzahl, die Farbtablette colors und
color=Genre. Die Unterschiede sind hier der type
parameter welcher auf scatter gesetz wird, mode welches none
ist und fill welches durch tozeroy die füllung bis zur
y Achse erzeugt.
grouped <- vgsales %>%
group_by(Year, Genre) %>%
dplyr::summarize(Anzahl =n()) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
`summarise()` has grouped output by 'Year'. You can override using the `.groups` argument.
filtered <- grouped %>% select(Year,Genre,Anzahl)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "Anzahl"
)
filtered %>%
plot_ly(x = ~Year, y = ~Anzahl, type = 'scatter', mode = 'none', fill = 'tozeroy',color = ~Genre ,colors = myPalette)%>%
layout(title="Anzahl der Spielereleases von 1980-2016",
xaxis = ax,
yaxis = ay
)
NA
Einige feinere unterschiede Lassen sich hier deutlich besser erkennen
als noch im Lines Diagramm. Man erkennt beispielsweise den großen
Wachstum von Strategy games zwischen 1996 und 1998 bevor diese 2000
stark abflachen und nicht mit dem allgemeinen Wachstum der anderen
Genres mithalten können. Auch der große Wachstum von Racing games
zwischen 200 und 2004 ist gut erkennbar.
Stacked Lines
Da stacked Lines sehr übersichtlich und gut darin sind sich einen
Groberen überblick über die Daten zu schaffen sind diese hier als erste
Ansicht vorausgewählt. Um die hinzugehörende Texte hundertprozentig
verstehen zu können ist es aber hilfreich zuerst den Lines und Filled
Lines tab zu studieren.
Die Erstellung des stacked Lines Diagramm ist den Filled Lines sehr
ähnlich. Einziger unterschied ist die Abwesenheit des fill
parameters und stattdessen die verwendung von stackgroup=‘one’
welches die stacked Lines erzeugt.
grouped <- vgsales %>%
group_by(Year, Genre) %>%
dplyr::summarize(Anzahl =n()) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
`summarise()` has grouped output by 'Year'. You can override using the `.groups` argument.
filtered <- grouped %>% select(Year,Genre,Anzahl)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "Anzahl"
)
filtered %>%
plot_ly(x = ~Year, y = ~Anzahl, type = 'scatter', mode = 'none', stackgroup = 'one',color = ~Genre, colors = myPalette)%>%
layout(title="Anzahl der Spielereleases von 1980-2016",
xaxis = ax,
yaxis = ay
)
NA
Leider sind die Farben aufgrund eines Fehlers hier etwas fehlerhaft
mehr dazu im Fazit Beim Betrachten
des Stacked Line plots sind jedoch trotzdem einige Dinge direkt sehr gut
zu erkennen. Man sieht welche Genres ein größeres Wachstum hinlegen als
andere. Sowohl Shooter als auch Puzzle und Platform Games bleiben in den
2010er jahren relativ gleichbleibend. Action, Strategz, Misc und Sports
Games können jedoch ein deutliches Wachstum aufzeigen.
Genreverschiebung
Schauen wir uns nun die Erstellung der zum vergleichen der Genres
wohl interessantesten Grafik an. Die erstellung ist hier quasi gleich zu
den Stacked Lines. Einzige neuerung ist das hinzufügen des Parameters
groupnorm = ‘percent’ welches die Y-Achse von dem wert der
Anzahl zu Prozentwerten ändert. Auch hier sind jedoch die Farben leider
Fehlerhaft.
grouped <- vgsales %>%
group_by(Year, Genre) %>%
dplyr::summarize(Anzahl =n()) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
`summarise()` has grouped output by 'Year'. You can override using the `.groups` argument.
filtered <- grouped %>% select(Year,Genre,Anzahl)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "Prozent %"
)
filtered %>%
plot_ly(x = ~Year, y = ~Anzahl, type = 'scatter', mode = 'none', stackgroup = 'one',groupnorm = 'percent',color = ~Genre ,colors = myPalette)%>%
layout(title="Marketshare Genreverschiebung in % von 1980-2016",
xaxis = ax,
yaxis = ay
)
Beim Betrachten fällt hier direkt auf, dass Action Games 1980-1984
einen großen Marktanteil, teilweise bis hin zu 50% ausgemacht haben.
Diese bis 1994 auf gerademal 3% absinken bevor der Stetige Wachstum
beginnt bis sie 2016 wieder bei Knap 40% enden. Auch die große
Marktpräsenz von Platform Spielen zwischen 1984 und 1992 ist gut
erkennbar wohingegen Racing Games sich zwischen 1994 und 2004 der
größten beliebtheit erfreuen.
Hierbei zu erkennen ist Obwohl die Anzahl der Jährlichen
Spielereleases über die Jahre hinweg stetig wächst bleiben die Meisten
Genres ähnlich viel vertreten. Auffällig sind hierbei Strategy-Games die
erst 1991 das erste mal auftretem Seitdem obwohl sie Leicht an
Marketshare verlieren grob gleich bleiben. Außerdem sind Action Games
die Spiele mit der wohl größten volatilität. Sind es 1982 noch fast 50%
der Gamereleases fällt deren aufkommen 1084 schon auf nur noch knapp 10%
ab und 1986 steigt der Wert wieder auf fast 30%. Dieser Trend setzt sich
fort bis 1996 ab welchem Zeitpunkt sich Action Games von 3.6% über die
Jahre bis 2016 bis 35% entwickeln.
Genreentwicklung im laufe der Jahre nach Verkaufszahlen
Schauen wir uns an wie sich die verkäufe entwickelt haben. Hierzu
verwenden wir die gleichen Diagramme wie bereits bei der Betrachtung der
Spiele Anzahl. Eine erklärung der erstellung der Diagramme gibt es hier.
Verkäufe pro Jahr
Lines
grouped <- vgsales %>%
group_by(Year, Genre) %>%
dplyr::summarize(gr_sum = sum(Global_Sales)) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
`summarise()` has grouped output by 'Year'. You can override using the `.groups` argument.
filtered <- grouped %>% select(Year,Genre,gr_sum)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "Verkäufe (in mio)"
)
filtered %>%
plot_ly() %>%
add_lines(x=~Year,
y=~gr_sum, color=~Genre ,colors = myPalette) %>%
layout(title="Verkaufszahlen der Spielereleases von 1980-2016",
xaxis = ax,
yaxis = ay
)
NA
Beim ersten Betrachten fällt hier direkt die hohe volatilität der
einzelnen Graphen auf, welches durch den hohen Einfluss einiger
gutlaufender Games auf die Verkaufszahlen zurückzuführen ist. Am
einfachsten ist dies zwischen 1980 und 1992 erkennbar. 1981 ist ein
spike in Action Games erkennbar, nametlich durch die veröffentlichung
namentlicher spiele wie Frogger und Pitfall. Im Jahr 1984 erkennbar ist
dann der spike von Shootern durch Duck-Game sowie Platform games in 1985
durch Super Mario Bros. Super Mario prägt die Historie der Platform
Games auch zwischen 1988 und 1990 mit Super Mario Bros 3 und Super Mario
World. Das Spiel welches 1989 einen ausschlag der Puzzle-Games
verursacht dürfte sogar Lesern, welche nicht Teil der Gaming-Community
sind ein begriff sein: Tetris.
Filled Lines
grouped <- vgsales %>%
group_by(Year, Genre) %>%
dplyr::summarize(gr_sum = sum(Global_Sales)) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
`summarise()` has grouped output by 'Year'. You can override using the `.groups` argument.
filtered <- grouped %>% select(Year,Genre,gr_sum)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "Verkäufe (in mio)"
)
filtered %>%
plot_ly(x = ~Year, y = ~gr_sum, type = 'scatter', mode = 'none', fill = 'tozeroy',color = ~Genre ,colors = myPalette) %>%
layout(title="Verkaufszahlen der Spielereleases von 1980-2016",
xaxis = ax,
yaxis = ay
)
NA
Durch Betrachten des Filled Line Plots erkennen wir gut den Hoch der
Strategiespiele im Jahr 1999 durch spiele wie Pokemon Stadium, Warzone
2100 oder Age of Empires II. Auch die Spikes der Role-Playing Games im
gleichen Jahr durch Pokemon Gold/Silber und Final Fantasy VIII sowie
1996 durch Pokemon Rot/Blau sind deutlich erkennbar.
Stacked Lines
grouped <- vgsales %>%
group_by(Year, Genre) %>%
dplyr::summarize(gr_sum = sum(Global_Sales)) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
`summarise()` has grouped output by 'Year'. You can override using the `.groups` argument.
filtered <- grouped %>% select(Year,Genre,gr_sum)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "Verkäufe (in mio)"
)
filtered %>%
plot_ly(x = ~Year, y = ~gr_sum, type = 'scatter', mode = 'none', stackgroup = 'one',color = ~Genre ,colors = myPalette)%>%
layout(title="Verkaufszahlen der Spielereleases von 1980-2016",
xaxis = ax,
yaxis = ay
)
Stacked Lines sind vermutlich das Beste Diagramm um Verkaufszahlen
mit der Anzahl zu vergleichen. Am auffälligsten hier sind, dass die
Volatilität in den früheren Jahren (1980-1995) bei geringerer präsenz
von Videospielen deutlich größer ausfällt als in der anzahl der
Videospiele. In den Späteren Jahren vorallem ab 2003 fallen die
Schwankungen hier jedoch deutlich geringer aus, was vermutlich an der
höheren Masse von Videospielen und damit einem breit gefächerterem
Nutzerinteresse liegt.
Genreverschiebung
grouped <- vgsales %>%
group_by(Year, Genre) %>%
dplyr::summarize(gr_sum = sum(Global_Sales)) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
`summarise()` has grouped output by 'Year'. You can override using the `.groups` argument.
filtered <- grouped %>% select(Year,Genre,gr_sum)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "Prozent %"
)
filtered %>%
plot_ly(x = ~Year, y = ~gr_sum, type = 'scatter', mode = 'none', stackgroup = 'one',groupnorm = 'percent',color = ~Genre ,colors = myPalette)%>%
layout(title="Marketshare Genreverschiebung in % von 1980-2016",
xaxis = ax,
yaxis = ay
)
Durch die hohe Volatilität ist die Grafik in den früheren Jahren
vorallem zwischen 1980 und 1992 sehr durcheinandern und Teilweise recht
schwierig zu lesen. In den darauf folgenden Jahren ist es aber deutlich
leichter bestimmte dinge wie das erstmalige auftretens der
Strategiespiele 1992 oder die fast Vollständige Abstinenz von Puzzle
Games zwischen 1995 und 2002 sowie ab 2012 zu erkennen.
Wie zu erwarten lässt sich hier ein Großer overlap zu den Anzahl der
Gamereleases feststellen es kann jedoch eine Hohe Volitilität durch
einzelne Spielereleases vorallem in früheren Jahren festgestellt werden.
Dies hat den Grund das einige “Kassenschlager” hier einen großteil des
Marktes ausmachen und ihn somit stark beeinflussen. Anzumerkten ist
jedoch das Spiele gerne Rereleast werden vorallem auf unterschiedlichen
Konsolen, dies in unserem Datensatz jedoch nicht zusammegeführt wird.
Weiteres hierzu im Fazit
Genreentwicklung im laufe der Jahre nach Verkaufszahlen pro
Spiel
Nachdem wir nun Analysiert haben wie sich die Anzahl der
Spielereleases sowie die Verkaufszahlen entwickelt haben wäre es doch
interessant beides gegenüberzustellen und direkt zu vergleichen. Hierzu
verwenden wir erneut die bereits bekannten Diagramme nutzen jedoch in der
dplyr::summarize() funktion die Summe der Verkaufszahlen welche
wir durch die Anzahl der Einträge teilen.
Verkäufe pro Spiel pro Jahr
Lines
grouped <- vgsales %>%
group_by(Year, Genre) %>%
dplyr::summarize(gr_sum = sum(Global_Sales)/n()) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
`summarise()` has grouped output by 'Year'. You can override using the `.groups` argument.
filtered <- grouped %>% select(Year,Genre,gr_sum)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "Verkäufe pro Spiel"
)
filtered %>%
plot_ly() %>%
add_lines(x=~Year,
y=~gr_sum, color=~Genre ,colors = myPalette) %>%
layout(title="Verkäufe pro Spiel nach Genre von 1980-2016",
xaxis = ax,
yaxis = ay
)
NA
Im Lines-Plot erkennen wir direkt die in der Verkaufszahlanalys genannten Extreme
welche durch einzelne Spiele, vorallem in den früheren Jahren,
beeinflusst werden. Am deutlichsten ist dies in Shooter Games 1984 durch
Duck-Game und Platform spiele 1985 durch Super Mario Bros. Auch Tetris
(Puzzle 1989) sowie Super Mario Bros 3 (Platform 1988) und Super Mario
World (Platform 1990) sind deutlich erkennbar. Neu erkennbar ist hier
der Ausschlag in Racing games 1992 durch den Klassiker Super Mario Kart
wessen Nachfolger bis heute auf fast jeder Nintendo Konsole
veröffentlicht wurden.
Filled Lines
In dem Fall der Verkäufe Pro Jahr sind die Stacked Lines leider wenig
ausschlaggebend und daher auch nicht als erste ansicht vorausgewählt.
Zum verstehen der Analyse sollte jedoch der Lines-Tab zuerst gelesen
werden.
grouped <- vgsales %>%
group_by(Year, Genre) %>%
dplyr::summarize(gr_sum = sum(Global_Sales)/n()) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
`summarise()` has grouped output by 'Year'. You can override using the `.groups` argument.
filtered <- grouped %>% select(Year,Genre,gr_sum)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "Verkäufe pro Spiel"
)
filtered %>%
plot_ly(x = ~Year, y = ~gr_sum, type = 'scatter', mode = 'none', fill = 'tozeroy',color = ~Genre ,colors = myPalette) %>%
layout(title="Verkäufe pro Spiel nach Genre von 1980-2016",
xaxis = ax,
yaxis = ay
)
NA
Beim Betrachten der Filled-Lines fällt auf das neben den Bereits
genannten Extremen Racing games auch im Jahre 1990 schon einen Hochpunkt
durch F-1 Race erfuhr. Auch das Extrem des Action genres 1987 durch
Zelda II: The Adventure of Link ist hier deutlicher erkennbar.
Stacked Lines
grouped <- vgsales %>%
group_by(Year, Genre) %>%
dplyr::summarize(gr_sum = sum(Global_Sales)/n()) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
`summarise()` has grouped output by 'Year'. You can override using the `.groups` argument.
filtered <- grouped %>% select(Year,Genre,gr_sum)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "Verkäufe pro Spiel"
)
filtered %>%
plot_ly(x = ~Year, y = ~gr_sum, type = 'scatter', mode = 'none', stackgroup = 'one',color = ~Genre, colors = myPalette)%>%
layout(title="Verkäufe pro Spiel nach Genre von 1980-2016",
xaxis = ax,
yaxis = ay
)
Stacked Lines ist hier für eine Analyse der einzelnen Spielegenres
leider nicht hilfreich. Der aufmerksame Beobachter wird sich jedoch an
eine der ersten Grafiken erinnern in denen wir die Sales pro Game analysiert haben und
sich Fragen warum die Werte hier deutlich höher ausfallen als noch
bevor. War in der Analyse ohne Genres der Maximalwert noch bei 4 so ist
er Hier bei mehr als 20. Dies liegt vorallem daran, dass Action games in
den Früheren Jahren einen großteil der Releases ausmachen bei den
verkaufszahlen aber eher gering ausfallen und den durchschnitt daher
herunterziehen. Sind die Spiele nach Genre aufgeteilt beeinflusst das
schlecht performende Action Genre die Verkaufszahlen pro Spiel der
anderen jedoch nicht und so erhalten wir additiv eine deutlich größere
Zahl als zuvor.
Genreverschiebung
grouped <- vgsales %>%
group_by(Year, Genre) %>%
dplyr::summarize(gr_sum = sum(Global_Sales)/n()) %>% filter(Year!='N/A')%>%filter(Year!=2020) %>% filter(Year!='2017') %>%
as.data.frame()
`summarise()` has grouped output by 'Year'. You can override using the `.groups` argument.
filtered <- grouped %>% select(Year,Genre,gr_sum)
ax <- list(
title = "Jahr"
)
ay <- list(
title = "Prozent %"
)
filtered %>%
plot_ly(x = ~Year, y = ~gr_sum, type = 'scatter', mode = 'none', stackgroup = 'one',groupnorm = 'percent',color = ~Genre, colors = myPalette)%>%
layout(title="Marketshare in Verkäufe pro Spiel nach Genre von 1980-2016",
xaxis = ax,
yaxis = ay
)
Durch die hohe volatilität in den Früheren Jahren ist auch hier wie
bei den Verkaufszahlen das Genreshift Diagramm wenig ausschlaggebend. AB
1994 kann man jedoch deutlich erkennen wir sich die Genres im laufe der
Jahre entwickeln. Shooter werden deutlich beliebter wohingegebn
Role-Playing games auf dem absteigenden Ast sind.
Auch hier ist wie erwartet die Entwicklung Prozentual ähnlich.
Auffällig ist jedoch das Shooter trotz ihrer geringen Vertretung in der
Prozentualen Verteilung 1984 sowie 2014,2015 und 2016 die Nase Vorne
haben. Platform Games haben 1985,1988 und 1990 die Nase Vorne. Die
Hochzeit der Puzzle Games sind unangefochten 1988 mit dem
Weltweitbekannten und auf Platz 6 der meistverkauften videospiele:
Tetris. Auffällig sind vorallem die Moderneren entwicklungen. Sind in
den 1996-2005er Jahren Role-Playing und somit langsame immersive
erlebnisse noch deutlich Beliebter haben heutzutage Shooter mit ihrem
Rundenbasiertem, “Fast Paced” also schnellem spielfluss die Nase Vorne.
In der Modernen Welt ist es deutlich einfacher und für Viele leute
weniger Zeitintensiv kurz eine Runde von 15-45 minuten zu spielen als
sich Stundenlang in eine Rolle hineinzuversetzen. Vielen Menschen fehlt
einfach Zeit oder Geduld um sich in der Zeit von modernen Medien wie
Tik-Tok oder Instagramm, welche sich auf kurze erlebnisse von oft
wenigen Sekunden spezialisiert haben, in ein Immersives erlebnis
hereinzuversetzen.
Genreverteilung nach Publisher
Da wir nun sowohl Genres als auch Publisher betrachtet haben wäre es
doch der einzig logische schritt diese beiden Daten zusammenzuführen und
zu vergleichen. Gibt es hier Publisher die verschiedene Genres
bevorzugen bzw. deren Bestseller sich in bestimmten Genres Tummeln?
Hierzu verwenden wir ein stacked Bar-Plot. Der beginn der
Diagrammerstellung ist hierbei ähnlich wie noch bei Paretodiagrammen. Relativ schnell fällt hier
jedoch auf das wir anstatt nur eines Dataframes Zwei Produzieren. Zum
einen der bereits bekannte grouped Dataframe welcher Publisher,
Genre und Verkaufszahlen ebenjener Genres beinhaltet. Zum anderen
PublisherSales welcher eine Liste der Publisher mit
Gesamtverkaufszahlen von mehr als 300 mio enthält. Diesen verwenden wir
im weiteren verlauf um aus unserem grouped Datensatz alle
Publisher zu entfernen die sich nicht in PublisherSales
befinden. Das geschieht mit hilfe des filter() commands und dem
Schlagwort %in%. Der rest der Diagrammerstellung verhält sich
equivalent zur Publisheranalyse mit dem
unterschied das die Bars bei der Diagrammerstellung nicht sortiert
werden.
Genreverteilung pro Publisher
Verkäufe
grouped <- vgsales %>%
group_by(Publisher,Genre) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
)
`summarise()` has grouped output by 'Publisher'. You can override using the `.groups` argument.
PublisherSales <- grouped %>%
group_by(Publisher) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
) %>% filter(Global_Sales>300)
grouped <- grouped %>% filter(Publisher %in% PublisherSales$Publisher)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
grouped$Publisher <-str_remove_all(grouped$Publisher, "Entertainment")
grouped$Publisher <-str_remove_all(grouped$Publisher, "Interactive")
grouped$Publisher <-str_remove_all(grouped$Publisher, "Studios")
grouped$Publisher <-str_remove_all(grouped$Publisher, "Games")
grouped$Publisher <-str_remove_all(grouped$Publisher, "Game")
ax <- list(
title = "Genre"
)
ay <- list(
title = "Verkäufe (in mio)"
)
grouped%>%
plot_ly(x=~Publisher,
y=~Global_Sales,
type='bar',
color=~Genre, colors = myPalette) %>%
layout(title="Verkäufe pro Genre pro Publisher",
xaxis = ax,
yaxis = ay,
barmode = 'stack'
)
NA
NA
Beim Betrachten der Verkaufszahlen fällt direkt auf, dass die meisten
Publisher bestimmte Genres präferieren. Activision haben mit Call of
Duty einen großteil ihrer verkäufe im Shooter Genre. Das Electronic Arts
mit FIFA und MaddenNFL im Sport Genre breit vertreten sind ist wenig
Verwunderlich. Shootern (Battlefield) und Racing (Need for Speed) sind
jedoch auch sehr Beliebte Genres bei dem US-basiertem Gaming riesen.
Nintendo spezifiziert sich wenig Verwunderlich auf Platform (Super
Mario) und Role-Playing(Pokemon). Sony hingegen fächern ihr angebot
relativ breit und haben neben 110.57 mio in Racing auch 104 mio in
Platform, 80 mio in Misc und 94.5 mio in Action. Take-Two mit Grand
Theft Auto und Read dead Redemption spezifieren sich wenig verwunderlich
auf Action wohingegen sich THQ wieder relativ breit fächert. Zu guter
letzt fährt Ubisoft eine zweigeteilte Schniene mit Action (Assassin’s
Creed) und Misc (Just Dance).
Anzahl
grouped <- vgsales %>%
group_by(Publisher,Genre) %>%
summarize(Anzahl =n(),sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
)
`summarise()` has grouped output by 'Publisher'. You can override using the `.groups` argument.
PublisherSales <- grouped %>%
group_by(Publisher) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
) %>% filter(Global_Sales>300)
grouped <- grouped %>% filter(Publisher %in% PublisherSales$Publisher)
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
grouped$Publisher <-str_remove_all(grouped$Publisher, "Entertainment")
grouped$Publisher <-str_remove_all(grouped$Publisher, "Interactive")
grouped$Publisher <-str_remove_all(grouped$Publisher, "Studios")
grouped$Publisher <-str_remove_all(grouped$Publisher, "Games")
grouped$Publisher <-str_remove_all(grouped$Publisher, "Game")
ax <- list(
title = "Genre"
)
ay <- list(
title = "Anzahl"
)
grouped%>%
plot_ly(x=~Publisher,
y=~Anzahl,
type='bar',
color=~Genre ,colors = myPalette) %>%
layout(title="Anzahl pro Genre pro Publisher",
xaxis = ax,
yaxis = ay,
barmode = 'stack'
)
NA
NA
NA
Betrachten wir die Anzahl der Spiele und stell diese den
Verkaufszahlen gegenüber fällt hier vorallem auf, dass Firmen mit Focus
in den Verkaufszahlen diese in der Produktion noch mehr Prioritisieren.
Interessant ist auch, das Activison produktionsfocus deutlich mehr auf
action Games liegt als auf Shootern diese sich im vergleich jedoch
deutlich schlechter verkaufen.
Bei dem vergleich der Werte ist hier zu bemerken, dass die meisten
Publisher Hierbei sich mit der Anzahl der Spiele und den Sales gut
abdecken. Die auffälligsten diskrepanzen sind hierbei EA mit dem Sports
Genre und ihren järlich releasten Spielen FiFa/NBA2k etc. sowie Nintendo
mit der Platformreihe Super Mario.
Genreverteilung für Publisher Electronic Arts
Schauen wir uns diese Beiden Firmen noch einmal im Detail an. Hierzu
verwenden wir erneut Pareto- und Kreisdiagramm die uns bereits aus
vorderen Teilen der Ausarbeitung bekannt sind.
Genre für Electronic Arts
Balkendiagramme
Verkaufszahlen
grouped <- vgsales %>%
group_by(Publisher,Genre) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
) %>%
filter(Publisher == "Electronic Arts")
`summarise()` has grouped output by 'Publisher'. You can override using the `.groups` argument.
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ax <- list(
title = "Genre"
)
ay <- list(
title = "Verkäufe (in mio)"
)
grouped%>%
plot_ly() %>% add_bars(x=~Genre,
y=~Global_Sales,
color=~Genre ,colors = myPalette) %>%
layout(title="Verkaufszahlen für Electronic Arts",
xaxis = ax,
yaxis = ay,
barmode = 'stack',
showlegend = FALSE
)
NA
Beim Betrachten der Sales erkennen wir das wie bereits vorher
festgestellt Sports (479.67 mio) an erster Stelle steht. Mit deutlichem
Abstand danach folgen Shooter (158.26 mio), Racing (145.77 mio) und
Action (115.54 mio). Das einzig andere Relevante Genre ist Simulation
mit 89.53 mio in Sales. Role-Playing (35.3 mio), Fighting (31.39 mio),
Misc (24.95 mio) sowie Strategy (14.08 mio), Platform (6.53 mio),
Adventure (4.75 mio) und Puzzle (4.55 mio) spielen eine eher
untergeordnete Rolle.
Anzahl
grouped <- vgsales %>%
group_by(Publisher,Genre) %>%
summarize(Anzahl =n()) %>%
filter(Publisher == "Electronic Arts")
`summarise()` has grouped output by 'Publisher'. You can override using the `.groups` argument.
ax <- list(
title = "Genre"
)
ay <- list(
title = "Anzahl"
)
grouped%>%
plot_ly() %>% add_bars(x=~Genre,
y=~Anzahl,
color=~Genre ,colors = myPalette) %>%
layout(title="Anzahl der Spielereleases nach Genre für Electronic Arts ",
xaxis = ax,
yaxis = ay,
barmode = 'stack',
showlegend = FALSE
)
NA
In der Detaillansicht sehen Anzahl der Spiele und Sales deutlich
geringer aus. Den ersten Platz belegt weiterhin Sports (561) vor Action
(183), Racing (159), Shooter (139) und Simulation (116). Auch die eher
irelevanten Genres wie Misc (46), Fighting (39) und Strategy (37) sind
weiterhin kaum vertreten.
Kreisdiagramme
Verkaufszahlen
grouped <- vgsales %>%
group_by(Publisher,Genre) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
) %>%
filter(Publisher == "Electronic Arts")
`summarise()` has grouped output by 'Publisher'. You can override using the `.groups` argument.
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ax <- list(
title = "Genre"
)
ay <- list(
title = "Verkäufe (in mio)"
)
grouped%>%
plot_ly() %>%
add_pie(values =~Global_Sales,labels=~Genre,textinfo='label+percent', rotation = 110, sort = FALSE,
name="Verkaufszahlen pro Genre für Electronic Arts" ,colors = myPalette) %>%
layout(title="Verkaufszahlen pro Genre für Electronic Arts",
xaxis = ax,
yaxis = ay,
showlegend = FALSE,
autosize = F
)
NA
NA
Beim Betrachten der Sales erkennen wir das wie bereits vorher
festgestellt Sports (43.2%) an erster Stelle steht. Mit deutlichem
Abstand danach folgen Shooter (14.3%), Racing (13.1%) und Action
(10.4%). Das einzig andere Relevante Genre ist Simulation mit 8.06% der
Sales. Role-Playing (3.18%), Fighting (2.83%), Misc (2.25%) sowie
Strategy (1.27%), Platform (0.588%), Adventure (0.428%) und Puzzle
(0.41%) spielen eine eher untergeordnete Rolle.
Amnzahl
grouped <- vgsales %>%
group_by(Publisher,Genre) %>%
summarize(Anzahl =n()) %>%
filter(Publisher == "Electronic Arts")
`summarise()` has grouped output by 'Publisher'. You can override using the `.groups` argument.
ax <- list(
title = "Genre"
)
ay <- list(
title = "Anzahl"
)
grouped%>%
plot_ly() %>%
add_pie(values =~Anzahl,labels=~Genre,textinfo='label+percent',sort = TRUE, rotation = 90,
name="Anzahl der Spielereleases pro Genre für Electronic Arts" ,colors = myPalette) %>%
layout(title="Anzahl der Spielereleases pro Genre für Electronic Arts",
xaxis = ax,
yaxis = ay,
showlegend = FALSE,
autosize = F
)
NA
In der Detaillansicht sehen Anzahl der Spiele und Sales deutlich
geringer aus. Den ersten Platz belegt weiterhin Sports (41.5%) vor
Action (13.5%), Racing (11.8%), Shooter (10.3%) und Simulation (8.59%).
Auch die eher irelevanten Genres wie Misc (3.4%), Fighting (2.89%) und
Strategy (2.74%) sind weiterhin kaum vertreten.
Schauen wir uns EA hier im Detail an fällt auf das die Diskrepanz
zwischen Sales und Anzahl der Gamereleases für EA bei Sports gar nicht
so groß ist (41.5% vs 43.2%) wie vorher gedacht. Die größeren
diskrepanzen sind hier Shooter welches nur 10% der Gamereleases sind
aber gut 15% der Sales und Action mit 13.5% der Gamereleases und 10.4%
der Sales.
Genreverteilung für Nintendo
Nachdem wir nun herausgefunden haben das bei Electronic Arts die
Diskrepanz zwischen Sales und Anzahl der Spiele gar nicht so groß ist
wie vorher gedacht betrachten wir nun die gleichen Daten für Nintendo.
Die Frage die sich hier stellt ist ob bei Nintendo ein ähnlicher verlauf
feststellbar ist oder ob sich bei diesen bestimmte Genres einfach
deutlich besser verkaufen als sie sollten.
Genreverteilung für Nintendo
Balkendiagramme
Verkaufszahlen
grouped <- vgsales %>%
group_by(Publisher,Genre) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
) %>%
filter(Publisher == "Nintendo")
`summarise()` has grouped output by 'Publisher'. You can override using the `.groups` argument.
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ax <- list(
title = "Genre"
)
ay <- list(
title = "Verkäufe (in mio)"
)
grouped%>%
plot_ly() %>% add_bars(x=~Genre,
y=~Global_Sales,
color=~Genre ,colors = myPalette) %>%
layout(title="Verkaufszahlen pro Genre für Nintendo",
xaxis = ax,
yaxis = ay,
barmode = 'stack',
showlegend = FALSE
)
NA
NA
Wie bereits in der Genreanalyse der
Publisher festgestellt verkaufen sich Platform-Spiele (427.21 mio)
für Nintendo am besten. Doch auch Role-Playing (284.9 mio), Sports (218
mio) und Misc (180.67 mio) machen keinen unwesentlichen Teil ihrer
Verkäufe aus. Selbst die weniger Prominenten Genres wie Racing (151.3
mio), Action (128.18 mio) und Puzzle (124.88 mio). verkaufen sich
immernoch deutlich besser als die entsprechenden Spielegenres der
Konkurrenz EA. Am deutlichsten ist der Unterschied vermutlich bei den
ganz “kleinen” Genres Simulation (85.27 mio), Shooter (69.73 mio),
Fighting (53.35 mio) und Adventure (35.71). Auch wenn diese sich nicht
an der Exakt gleichen stelle in der Rangliste der Sales befinden hat der
letzte Platz von Nintendo Strategy (27.35%) dennoch mehr als das 6 Fache
an Sales als der von EA. Trotz das Nintendo mehr Total Sales hat als
Electronic Arts ist dieser wert nicht 6 mal so groß sondern umfasst
nichtmal das doppelte.
Anzahl
grouped <- vgsales %>%
group_by(Publisher,Genre) %>%
summarize(Anzahl =n()) %>%
filter(Publisher == "Nintendo")
`summarise()` has grouped output by 'Publisher'. You can override using the `.groups` argument.
ax <- list(
title = "Genre"
)
ay <- list(
title = "Anzahl"
)
grouped%>%
plot_ly() %>% add_bars(x=~Genre,
y=~Anzahl,
color=~Genre ,colors = myPalette) %>%
layout(title="Anzahl der Spielereleases nach Genre für Nintendo",
xaxis = ax,
yaxis = ay,
barmode = 'stack',
showlegend = FALSE
)
NA
Im ersten Moment fällt direkt auf, dass der Ausschlag von Platform
(112) hier deutlich geringer ausfällt als noch in den Verkaufszahlen.
Sowohl Role-Playing (106) als auch Misc (100) umfassen nur ein paar
weniger Spiele. Auch das Mittelfeld umfasst mit Action (79), Puzzle (74)
und Sports (55) immernoch eine Relativ große Anzahl an Spielen. Selbst
die hinteren Plätze mit Racing (37), Adventure (35) und Strategy (32)
sind nur knapp vor Simulation (29), Shooter (26) und Fighting (18).
Kreisdiagramme
Verkaufszahlen
grouped <- vgsales %>%
group_by(Publisher,Genre) %>%
summarize(sum(Global_Sales)) %>%
rename(
Global_Sales = "sum(Global_Sales)"
) %>%
filter(Publisher == "Nintendo")
`summarise()` has grouped output by 'Publisher'. You can override using the `.groups` argument.
grouped$Global_Sales<-as_vector(grouped$Global_Sales)
ax <- list(
title = "Genre"
)
ay <- list(
title = "Verkäufe (in mio)"
)
grouped%>%
plot_ly() %>%
add_pie(values =~Global_Sales,labels=~Genre,textinfo='label+percent',sort = TRUE,
name="Verkäufe nach Genre für Nintendo" ,colors = myPalette) %>%
layout(title="Verkäufe nach Genre für Nintendo",
xaxis = ax,
yaxis = ay,
showlegend = FALSE,
autosize = F
)
NA
NA
Wie bereits in der Genreanalyse der
Publisher festgestellt verkaufen sich Platform-Spiele (23.9%) für
Nintendo am besten. Doch auch Role-Playing (15.9%), Sports (12.2%) und
Misc (10.1%) machen keinen unwesentlichen Teil ihrer Verkäufe aus.
Selbst die weniger Prominenten Genres wie Racing (8.47%), Action (7.17%)
und Puzzle (6.99%). verkaufen sich immernoch deutlich besser als die
entsprechenden Spielegenres der Konkurrenz EA. Am deutlichsten ist der
Unterschied vermutlich bei den ganz “kleinen” Genres Simulation (4.77%),
Shooter (3.9%), Fighting (2.99%) und Adventure (2%). Auch wenn diese
sich nicht an der Exakt gleichen stelle in der Rangliste der Sales
befinden hat der letzte Platz von Nintendo Strategy (1.53%) dennoch mehr
als das 6 Fache an Sales als der von EA. Trotz das Nintendo mehr Total
Sales hat als Electronic Arts ist dieser wert nicht 6 mal so groß
sondern umfasst nichtmal das doppelte.
Anzahl
grouped <- vgsales %>%
group_by(Publisher,Genre) %>%
summarize(Anzahl =n()) %>%
filter(Publisher == "Nintendo")
`summarise()` has grouped output by 'Publisher'. You can override using the `.groups` argument.
ax <- list(
title = "Genre"
)
ay <- list(
title = "Anzahl"
)
grouped%>%
plot_ly() %>%
add_pie(values =~Anzahl,labels=~Genre,textinfo='label+percent',sort = TRUE,
name="Anzahl nach Genre für Nintendo" ,colors = myPalette) %>%
layout(title="Anzahl nach Genre für Nintendo",
xaxis = ax,
yaxis = ay,
showlegend = FALSE
)
NA
Im ersten Moment fällt direkt auf, dass der Ausschlag von Platform
(15.9%) hier deutlich geringer ausfällt als noch in den Verkaufszahlen.
Sowohl Role-Playing (15.1%) als auch Misc (14.1%) umfassen nur ein paar
weniger Spiele. Auch das Mittelfeld umfasst mit Action (11.2%), Puzzle
(10.5%) und Sports (7.82%) immernoch eine Relativ große Anzahl an
Spielen. Selbst die hinteren Plätze mit Racing (5.26%), Adventure
(4.98%) und Strategy (4.55%) sind nur knapp vor Simulation (4.13%),
Shooter (3.7%) und Fighting (2.56%).
Beim vergleichen der Werte von Nintendo wird einem aufmerksamen
beobachter ziemlich schnell klar, dass Platform Spiele ein Kassenchlager
sind. Nehmen diese nur 16% der spielereleases ein so bringen sie dennoch
24% der Sales ein. Gleiches Gilt für Sport games. 8% gegenüber 12%.
Action (11% vs 7%), Misc (14% vs 10%) und Puzzle Games (10.5% vs 7%)
sind jedoch nicht so erfolgreich. Die Frage woran dies liegen könnte
wäre bestimmt auch eine interessante und etwas für einen Ausblick in die Zukunft
Ausblick in die Zukunft
Bei der Analyse des Datensatzes beziehungsweise der Entstandenen
Grafiken sind sowohl dem Aufmerksamen leser als auch mir dem Ersteller
einige weiter Ideen beziehungsweise weitere Ansätze gekommen die mit
sicherheit interessant wären zu Verfolge. Einige dieser Beispiele habe
ich im Folgenden als Ideen für Zukünftige Projekte
Niedergeschrieben.
Beim Vergleich der allgemeinen Game
Sales haben wir ausschläge Festgestellt die möglicherweise etwas mit
bestimmten Videospielen oder andere äußeren Einflussfaktoren wie den
einfacheren Zugriff auf Konsolen, eine breitere Akzeptanz für
Videospiele oder die Entwicklung des Internets. Eine genauere Analyse
der Ausschläge wäre dementsprechend ein Interessantes Thema.
Interessant wäre Demtnsprechend auch eine genauere Analyse der
Gamesales pro Jahr also in welchem Jahr welches Spiel wie oft gekauft
wurde. Wurde Beispielsweise Tetris 1950 30 mal und 2015 300.000 mal
verkauft. Dies geben die vorliegenden Daten jedoch leider nicht her also
wäre ein andere Datensatz bzw weitere Daten notwendig.
Im gleichen Gedankenschritt kommt eine analyse der Veränderungen
im Kaufverhalten während der Cronapandemie und dem darauf folgenden
Lockdown ist aber aus gleichem Grund leider nicht möglich.
Das Gleiche Trifft auf die Verkaufszhlentwicklung im laufe der Jahre
mit einer genauern Analyse der verkauften Spiele pro Platform im laufe
der Jahre zu.
Desweiteren haben wir uns beim vergleich der Platformen die Frage gestellt wie sich die
Spieleverkäufe pro Platform verhalten. Ein Vergleich ebenjener Daten
währe dementsprechend interessant um zu klären ob sich Biespielsweise
Nintendospiele besser auf Nintendo konsolen oder Sony Spiele besser auf
der Playstation verkaufen. Dies benötigt jedoch vorallem aufgrund von
Exklusivtiteln wie “The Legend of Zelda: Breath of the Wild” oder “God
of War” extensive analysearbeit.
In der Publisheranalyse haben
wir uns Anzahl der Spielereleases sowie Anzahl der Verkäufe verglichen.
Interreant währe hier ein direkter 1 zu 1 vergleich möglicherweise sogar
unter bezugnahme auf Platformen und Genres.
Ein vergleich der Spiele nach Herstellerregion in der Platformanalys wäre sehr interessant gewesen
ist jedoch anhand des Datensatzes leider nicht möglich. Selbst eine
annahme des Herkunftslandes anhand des Publishers ist nicht möglich da
viele Publisher Studios in unterschiedlichsten Ländern und Regionen
betreibt. Ubisoft hat beispielsweise Standorte in Paris, Mainz, New York
und Singapur.
Ein Regionaler vergleich anhand der Einwohnerzahlen einer Region
bzw allgemein ein Vergleich der Spieleverkäufe mit der Entwicklung der
Weltbevölkerung, welche sich seit 1980 fast
verdoppelt hat.
Dies ist nur ein kleiner ausschnitt der schier unendlichen
Möglichkeiten die einem bei der Analyse von den mittlerweile mehr als 4
mio Videospielen bleibt und das nur angenommen wir bleiben bei einem
eher allgemeinerem Vergleich. Jedes dieser Videospiele hat vermutlich
genug öffentliche Daten um eine Arbeit zu produzieren die ein vielfaches
des Volumens dieser Arbeit, für welche mir nur knapp 70h zu Verfügung
standen, hat.
Aufgetretene Probleme
Nun aber zu dem unschönen teil einer jeder Arbeit. Den aufgetretenen
Problemen, welche entweder nicht lösbar oder eine relativ starke
überarbeitung der Ausarbeitung nachziehen würden.
Das Erste und für den Aufmerksamen Leser, welcher sich vorallem
die Line Plots im direkten vergleich angeschaut hat, offensichtliche.
Der am Anfag erstellte Colorbrewer, welcher die Farben für die Grafiken
liefert wird aus irgendeinam Grund nicht in jeder Grafik akzeptiert.
Dies scheint hier rein zufällig zu sein und folgt keinem
offensichtlichem Pattern. Der Einziger unterschied zwischen Filled Lines
und Stacked Lines ist die Abwesenheit des fill parameters und
stattdessen die verwendung von stackgroup=‘one’. Trotz diesen
minimalen unterschiedes Akzeptiert die Filled Lines Grafik die
Farbauswahl, Stacked Lines jedoch nicht.
Ein weiterer mir unerklärlicher Fehler in der Dokumenterstellung
ist die änderung des Formats nach dem importieren der Librarys. Es gibt
keinen offensichtlichen Grund warum sich hier das Format ändern sollte
auf einmal füllt der Text jedoch 100% des Bildschirms was z.T. zu sehr
schwer zu leseneden Worten führt.
Wie bereits in der Analyse der Sales per Game per Year
festgestellt werden Spiele häufig auf mehreren Konsolen veröffentlicht.
Eine zusammenfassung der Spiele zum Zweck der Sales per Game Analyse wäre dafür
vonnöten.
Bei Betrachtung des Codes, welcher die Grafiken erzeugt wird den
meisten auffallen, dass oft doppelter Code durch verwendung in mehreren
Diagrammen mit nur leichten Änderungen entsteht. Zusammenfassung ist
hier durch die Nutzung von mehreren Data Frames und anwendung der
jeweiligen durchaus möglich benötigt jedoch zum Teil gravierende
überarbeitung der einzelnen Abschnitte.
Ein Filtern der Platformverkäufe pro
Jahr nach total Sales wäre deutlich besser als ein Filtern nach den
Sales in einem Jahr. Dies würde die Erzeugung eines zusätzlichen Data
Frames benötigen wäre jedoch deutlich informativer als der aktuelle
stand bei dem einige Jahre ganz aus dem Shema fallen.
Das Publischer Ranking nach
Region würde vermutlich vorallem die kleinere Region Japan einen
deutlich anderen ausgang aufzeigen, sollte nicht nach der Anzahl der
Spiele sondern beispielsweise dem wert der Verkaufszahlen gefiltert
werde. Dies führt jedoch dazu, dass unterschiedlichen Publisher
verglichen werden was den informationsgehalt minimieren würde.
Bei der Platformanalys wird den
meisten, vorallem nicht Gamingversierten Lesern aufgefallen sein das
Mobilegames im Datensatz komplett fehlen. Als die wohl am weit
vertretenste und mittlerweile umsatzstärkste
Platform beeinflusst dies den Datensatz ungemein. Allgemein sind nur
knapp 16.000 der weltweit mehr als 3.3
mio Videospiele in dem Datensatz vorhanden.
Nun zu Vermutlich dem größten Problem neben den bereits vorherig
etwähnten fehlenden Daten. Viele spiele werden auf verschiedenen
Platformen, zum teil auf Konkurrenten oder nachfolgern rereleast. Das
bedeutet das ein Spiel für mehrere Konsolen veröffentlicht wird. Diese
Daten werdem im Vorhandenen Datensatznicht zusammengeführt und kommen
dementsprechend mehrmals vor. Super Mario bros existiert beispielsweise
13 mal und Grand Theft Auto 4 belegt platz 52 auf der xboX360 und Platz
57 auf der PS3.
Literatur und Quellenverzeichnis
LS0tDQp0aXRsZTogIlZpZGVvc3BpZWwgVmVya8OkdWZlIg0Kb3V0cHV0OiANCiAgIA0KICAgaHRtbF9kb2N1bWVudCA6IA0KICAgICAgaW5jbHVkZXM6DQogICAgICAgIGFmdGVyX2JvZHk6IGZvb3Rlci5odG1sDQogICAgICB0aGVtZTogY29zbW8NCiAgICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgaHRtbF9ub3RlYm9vayA6IA0KICAgICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgICBpbmNsdWRlczoNCiAgICAgICAgYWZ0ZXJfYm9keTogZm9vdGVyLmh0bWwNCiAgICAgIHRoZW1lOiBjb3Ntbw0KLS0tDQo8Y2VudGVyPiFbXShWaWRlb2dhbWVzLnBuZykgPC9jZW50ZXI+DQo8Y2VudGVyPiANCiMgRmxvcmlhbiBSZWljaGxlIA0KPC9jZW50ZXI+DQoqKioNCg0KIyMjICoqQW5nYWJlbiB6dSBkZW4gRGF0ZW4qKg0KRGFzIHZlcndlbmRldGUgRGF0YXNldCBkZXMgUHJvamVrdHM6IGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvZ3JlZ29ydXQvdmlkZW9nYW1lc2FsZXMgICANCkRpZXMgYmVzdGVodCBhdXMgZGVuIERhdGVuIHZvbiBodHRwczovL3d3dy52Z2NoYXJ0ei5jb20vIGbDvHIgZGllIEphaHJlIDE5ODAgYmlzIDIwMTYgdW5kIHVtZmFzc3QgZGllIEZvbGdlbmRlbiBTcGFsdGVuIGJ6dy5EYXRlbi4NCg0KKiBSYW5rIC0gRGllIFBsYXR6aWVydW5nIGRlcyBTcGllbHMgbmFjaCBBbnphaGwgZGVyIFZlcmvDpHVmZW4NCiogTmFtZSAtIERlciBOYW1lIGRlcyBTcGllbHMNCiogUGxhdGZvcm0gLSBEaWUgUGxhdGZvcm0gYXVmIGRlciBkYXMgU3BpZWwgdmVyw7ZmZmVudGxpY2h0IHd1cmRlICh6LkIuIFBDLFBTNCwgZXRjLikNCiogWWVhciAtIERhcyBKYWhyIGRlciBWZXLDtmZmZW50bGljaHVuZyBkZXMgU3BpZWxzDQoqIEdlbnJlIC0gRGFzIEdlbnJlIGRlcyBTcGllbHMgKHouQi4gU3BvcnQsQWN0aW9uLCBQdXp6bGUpDQoqIFB1Ymxpc2hlciAtIERlciBQdWJsaXNoZXIgZGVzIFNwaWVscw0KKiBOQV9TYWxlcyAtIERpZSBBbnphaGwgZGVyIFZlcmvDpHVmZSBpbiBOb3JkLUFtZXJpa2EgKGluIG1pbGxpb25lbikNCiogRVVfU2FsZXMgLSBEaWUgQW56YWhsIGRlciBWZXJrw6R1ZmUgaW4gRXVyb3BhIChpbiBtaWxsaW9uZW4pDQoqIEpQX1NhbGVzIC0gRGllIEFuemFobCBkZXIgVmVya8OkdWZlIGluIEphcGFuIChpbiBtaWxsaW9uZW4pDQoqIE90aGVyX1NhbGVzIC0gRGllIEFuemFobCBkZXIgVmVya8OkdWZlIGltIFJlc3QgZGVyIFdlbHQgKGluIG1pbGxpb25lbikNCiogR2xvYmFsX1NhbGVzIC0gRGllIEFuemFobCBkZXIgVmVya8OkdWZlIFdlbHR3ZWl0IChpbiBtaWxsaW9uZW4pDQoNCioqKg0KDQojIyMgKipJbmhhbHRzdmVyemVpY2huaXMqKg0KDQoNCjEuIFJlbGVhc2VhbmFseXNlDQogICAgKyBbbmFjaCBBbnphaGxdKCNWaWRlb0dhbWVSZWxlYXNlcykNCiAgICArIFtuYWNoIFNhbGVzXSgjVmlkZW9HYW1lUmVsZWFzZXMpDQogICAgKyBbbmFjaCBTYWxlcyBwcm8gR2FtZV0oI1ZpZGVvR2FtZVJlbGVhc2VzKQ0KICAgIA0KMi4gUGxhdGZvcm1hbmFseXNlDQogICAgKyBbR2xvYmFsXSgjUGxhdGZvcm1hbmFseXNlKQ0KICAgICsgW25hY2ggUmVnaW9uXSgjUGxhdGZvcm1SYW5raW5nQnlSZWdpb24pDQogICAgKyBbVmVya2F1ZnN6aGxlbnR3aWNrbHVuZyBpbSBsYXVmZSBkZXIgSmFocmVdKCNTYWxlc1BlclBsYXRmb3JtKQ0KICAgIA0KMy4gUHVibGlzaGVyYW5hbHlzZSANCiAgICArIFtHbG9iYWxdKCNQdWJsaXNoZXJSZWxlYXNlcykNCiAgICArIFtuYWNoIFJlZ2lvbl0oI1B1Ymxpc2hlclJhbmtpbmdieVJlZ2lvbikNCiAgICANCjQuIEdlbnJlYW5hbHlzZQ0KICAgICsgW25hY2ggQW56YWhsXSgjR2VucmVBbW91bnRHbG9iYWwpDQogICAgKyBbbmFjaCBWZXJrYXVmc3phaGxlbl0oI0dlbnJlU2FsZXNHbG9iYWwpDQogICAgKyBbbmFjaCBSZWdpb25dKCNHZW5yZUFtb3VudEJ5UmVnaW9uKQ0KICAgIA0KNS4gR2VucmV2ZXJ0ZWlsdW5nIHBybyBKYWhyDQogICAgKyBbbmFjaCBBbnphaGxdKCNHZW5yZUFtb3VudFBlclllYXIpDQogICAgKyBbbmFjaCBWZXJrYXVmc3phaGxlbl0oI0dlbnJlU2FsZXNQZXJZZWFyKQ0KICAgICsgW25hY2ggVmVya2F1ZnN6YWhsZW4gcHJvIFNwaWVsXSgjR2VucmVTYWxlc1BlckdhbWVQZXJZZWFyKQ0KICAgIA0KNi4gUHVibGlzaGVyIEdlbnJlcw0KICAgICsgW2bDvHIgZGllIFRvcCBQdWJsaXNoZXJdKCNHZW5yZUJ5UHVibGlzaGVyR2xvYmFsKQ0KICAgICsgW0RldGFpbGFuYWx5c2UgRWxlY3Ryb25pYyBBcnRzXSgjR2VucmVCeVB1Ymxpc2hlckVBKQ0KICAgICsgW0RldGFpbGFuYWx5c2UgTmludGVuZG9dKCNHZW5yZUJ5UHVibGlzaGVyTmludGVuZG8pDQogICAgDQo3LiBLcml0aXNjaGVyIFLDvGNrYmxpY2sNCiAgICArIFtBdXNibGljayBpbiBkaWUgWnVrdW5mdF0oI0F1c2JsaWNrSW5EaWVadWt1bmZ0KQ0KICAgICsgW0F1ZmdldHJldGVuZSBQcm9ibGVtZV0oI0F1ZmdldHJldGVuZVByb2JsZW1lKQ0KICAgICsgW0xpdGVyYXR1cnZlcnplaWNobmlzXSgjTGl0ZXJhdHVydmVyemVpY2huaXMpDQoNCioqKg0KIyMjIFRoZXNlbg0KDQpCZXZvciB3aXIgbWl0IGRlciBBbmFseXNlIGRlciBEYXRlbiBiZWdpbm5lbiBrw7ZubmVuIFN0ZWxsZW4gd2lyIGVyc3RtYWwgZWluIHBhYXIgVGhlc2VuIGJ6dy4gRnJhZ2VzdGVsbHVuZ2VuIGF1ZiBkaWUgd2lyIGltIGxhdWZlIGRlcyBQcm9qZWt0cyBoaW50ZXJmcmFnZW4gYnp3IGJlYW50d29ydGVuIHdvbGxlbi4gIA0KDQoqIFdlbGNoZSBKYWhyZSBzaW5kIGRpZSBiZXN0ZW4gaW4gZGVyIEFuemFobCBkZXIgcmVsZWFzdGVuIEdhbWVzIHVuZCBTYWxlcz8gIFtBbnR3b3J0XSgjVmlkZW9HYW1lUmVsZWFzZXMpDQoqIFdlcmRlbiBoZXV0enV0YWdlIG1laHIgU3BpZWxlIFJlbGVhc3QgdW5kIFZlcmthdWZ0IGFscyBub2NoIDE5ODA/IFtBbnR3b3J0XSgjVmlkZW9HYW1lUmVsZWFzZXMpDQoqIFdlbGNoZSBKYWhyZSBzaW5kIGRpZSBiZXN0ZW4gaW4gQW56YWhsIFNhbGVzIHBybyBHYW1lPyBXZXJkZW4gbmV1ZXJlIFNwaWVsZSBhdXRvbWF0aXNjaCBtZWhyIEdla2F1ZnQ/IFtBbnR3b3J0XSgjVmlkZW9HYW1lUmVsZWFzZXMpDQoNCiogV2VsY2hlIFBsYXR0Zm9ybSBpc3QgZGllIGJlc3RlIGluIEFuemFobCB2ZXJrw6R1ZmVuPyBXZWxjaGUgaW4gQW56YWhsIGRlciBHYW1lIFJlbGVhc2VzPyBbQW50d29ydF0oI1BsYXRmb3JtYW5hbHlzZSkNCiogSGFiZW4gw4RsdGVyZSBQbGF0Zm9ybWVuIEF1dG9tYXRpc2NoIG1laHIgU3BpZWxlIHVuZCBWZXJrw6R1ZmU/IFtBbnR3b3J0XSgjUGxhdGZvcm1SYW5raW5nR2xvYmFsX0VuZCkNCiogRmF2b3Jpc2llcmVuIHZlcnNjaGllZGVuZSBSZWdpb25lbiB2ZXJzY2hpZWRlbmUgUGxhdGZvcm1lbj8gVmVya2F1ZmVuIGRpZSBSZWdpb25lbmhlaW1pc2NoZW4gUGxhdGZvcm1lbiBhdXRvbWF0aXNjaCBhdWNoIGRpZSBtZWlzdGVuIFNwaWVsZT8gW0FudHdvcnRdKCNQbGF0Zm9ybVJhbmtpbmdCeVJlZ2lvbikNCiogV2llIEVudHdpY2tlbG4gc2ljaCBkaWUgVmVya8OkdWZlIHBybyBQbGF0Zm9ybSBpbSBsYXVmZSBkZXIgSmFocmU/IEhhYmVuIFBsYXRmb3JtZW4ga3VyeiBuYWNoIFJlbGVhc2UgZGVuIGdyw7bDn3RlbiAiSHlwZSI/IFtBbnR3b3J0XSgjU2FsZXNQZXJQbGF0Zm9ybSkNCg0KKiBCZXN0aW1tdGUgUHVibGlzaGVyIGjDpHVmZW4gc2ljaCBpbiBBbnphaGwgZGVyIFNwaWVsZSB1bmQgZGVyIFZlcmvDpHVmZW4gKHouQi4gTmludGVuZG8sIEVBLCBBY3RpdmlzaW9uIEJsaXp6YXJkKSBbQW50d29ydF0oI1B1Ymxpc2hlclJlbGVhc2VzKSAgDQoqIEdpYnQgZXMgcmVnaW9uYWxlIFVudGVyc2NoaWVkZSBpbiBkZW4gUHVibGlzaGVybj8gV2VyZGVuIFJlZ2lvbmVuaW50ZXJuZSBQdWJsaXNoZXIgRmF2b3JpdGlzaWVydD8gW0FudHdvcnRdKCNQdWJsaXNoZXJSYW5raW5nYnlSZWdpb24pDQoNCiogV2llIHNpbmQgZGllIEdlbnJlcyBkZXIgU3BpZWxlIHZlcnRlaWx0PyBIw6R1ZmVuIHNpY2ggYmVzdGltbXRlIEdlbnJlcyBiZWkgQW56YWhsIHVuZCBWZXJrYXVmc3phaGxlbj8gR2lidCBlcyBHZW5yZXMgZGllIGJlc3Nlci9zY2hsZWNodGVyIFBlcmZvcm1lbiBhbHMgc2llIHNvbGx0ZW4/IFtBbnR3b3J0XSgjR2VucmVBbW91bnRHbG9iYWwpICAgDQoqIEdpYnQgZXMgcmVnaW9uYWxlIFVudGVyc2NoaWVkZSBpbiBkZW4gR2VucmVzPyAoR2lidCBlcyBSZWdpb25lbiBkaWUgU3BlemlmaXNjaGUgR2VucmVzIEZhdm9yaXNpZXJlbiB3ZWxjaGUgaW4gYW5kZXJlbiBSZWdpb25lbiBudXIgZWluZSBnZXJpbmdlIFJvbGxlIHNwaWVsdD8pIFtBbnR3b3J0XSgjR2VucmVBbW91bnRCeVJlZ2lvbikNCg0KKiBXaWUgaGFiZW4gc2ljaCBkaWUgR2VucmVzIMO8YmVyIGRpZSBKYWhyZSBlbnR3aWNrZWx0PyBbQW50d29ydF0oI0dlbnJlQW1vdW50UGVyWWVhcikNCiogR2lidCBlcyBHZW5yZXMgZGllIG1hbCBncm/Dn2VuIEVpbmZsdXNzIGhhdHRlbiB1bmQgbnVuIEJlZGV1dHVuZ3Nsb3Mgc2luZD8gW0FudHdvcnRdKCNHZW5yZVNhbGVzUGVyR2FtZVBlclllYXIpDQoNCiogR2lidCBlcyBQdWJsaXNoZXIgZGllIGJlc3RpbW10ZSBHZW5yZXMgYmV2b3J6dWdlbiBiencuIFB1Ymxpc2hlciBkZXJlbiBHYW1lcyBlaW5lcyBiZXN0aW1tdGVuIEdlbnJlcyBzaWNoIGJlc29uZGVycyBndXQgVmVya2F1ZmVuPyBbQW50d29ydF0oI0dlbnJlQnlQdWJsaXNoZXJHbG9iYWwpDQoNCg0KKioqDQoNCiMjIyBEYXRlbiB1bmQgTGlicmFyeXMNCk5hY2ggZGVtIFZvcnN0ZWxsZW4gZGVyIERhdGVuIHVuZCBkZW0gYXVmc3RlbGxlbiBkZXIgaW5pdGlhbGVuIFRoZXNlbiBrw7ZubmVuIHdpciBudW4gbWl0IGRlbSBlaW5sZXNlbiBkZXIgRGF0ZW4gYmVnaW5uZW4uICANClp1c8OkdHpsaWNoIGVyc3RlbGxlbiB3aXIgbm9jaCBlaW5lIEZhcmJwYWxldHRlIHVuZCBpbXBvcnRpZXJlbiBkaWUgTGlicmFyeXMNCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9VFJVRSwgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFfQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShmb3JjYXRzKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGtuaXRyLCB3YXJuLmNvbmZsaWN0cyA9IEZBTFNFLCBxdWlldGx5PVRSVUUpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkoZHlncmFwaHMpDQpsaWJyYXJ5KHh0cykNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KGRwbHlyKSkNCm15UGFsZXR0ZSA8LSBicmV3ZXIucGFsKDEwLCAiUGFpcmVkIikNCnZnc2FsZXMgPC0gcmVhZF9jc3YoInZnc2FsZXMuY3N2IikNCg0KYGBgDQoNCioqKg0KDQoNCiMgVmlkZW9zcGllbCByZWxlYXNlcyB7I1ZpZGVvR2FtZVJlbGVhc2VzfQ0KDQoNCiMjIFZpZGVvc3BpZWwgcmVsZWFzZXMgaW0gbGF1ZmUgZGVyIEphaHJlIHsudGFic2V0fQ0KIyMjIFJlbGVhc2VzIG5hY2ggQW56YWhsIHsjVmlkZW9HYW1lUmVsZWFzZXNBbW91bnR9DQoNClVuc2VyZSBlcnN0ZSBUaGVzZSB3YXIg4oCcV2VsY2hlIEphaHJlIHNpbmQgZGllIGJlc3RlbiBpbiBkZXIgQW56YWhsIGRlciByZWxlYXN0ZW4gR2FtZXMgdW5kIFNhbGVzP+KAnSBVbSBkaWVzZXIgRnJhZ2VzdGVsbHVuZyBhdWYgZGVuIEdydW5kIHp1IGdlaGVuIG3DvHNzZW4gd2lyIHp1ZXJzdCBlaW5tYWwgZGllIERhdGVuIGRlciBUYWJlbGxlIHZnc2FsZXMgbWl0aGlsZmUgZGVyIEZ1bmt0aW9uICpncm91cF9ieShZZWFyKSogYW5oYW5kIGRlciBKYWhyZSBadXNhbW1lbmZhc3Nlbi4gTnVuIGVyaGFsdGVuIHdpciBlaW5lIG5hY2ggZGVuIEphaHJlbiB6dXNhbW1lbmdlZmFzc3RlIFRhYmVsbGUgZGVyZW4gRWludHLDpGdlIHdpciBtaXQgZGVyIEZ1bmt0aW9uICpkcGx5cjo6c3VtbWFyaXplKEFuemFobCA9bigpKSogYWJ6w6RobGVuIHVuZCBhbHMgV2VydCBBbnphaGwgYWJzcGVpY2hlcm4uIEF1ZmdydW5kIGRlciBmw7xyIGRpZXNlIGFuYWx5c2UgRmVobGVyaGFmdGVuIERhdGVuIHZlcndlbmRlbiB3aXIgbm9jaCBkaWUgRnVua3Rpb24gKmZpbHRlcigpKiB1bSBhbGxlIGZlaGxlbmRlbiBKYWhyZXNlaW50csOkZ2Ugc293aWUgZGllIEphaHJlIDIwMjAgdW5kIDIwMTcgaGVyYXVzenVmaWx0ZXJuLiBMZXR6dGVyZSBKYWhyZSBzaW5kIGRhaGVyIGZlaGxlcmhhZnQsIGRhIGRlciBEYXRlbnNhdHogMjAxNiBlcnN0ZWxsdCB3dXJkZS4gRGllc2UgRGF0ZW4gc3BlaWNoZXJuIHdpciBhbHMgKmRhdGEuZnJhbWUqIGluIGRlciBWYXJpYWJsZSAqZ3JvdXBlZCogYWIuIEltIEZvbGdlbmRlbiB2ZXJ3ZW5kZW4gd2lyIGViZW5qZW5lcyBkYXRhLmZyYW1lIHVtIG51ciBkaWUgRWludHLDpGdlIEphaHIgdW5kIEFuemFobCB6dSBzZWxla3RpZXJlbiB1bmQgaW4gZGVyIFZhcmlhYmxlICpmaWx0ZXJlZCogYWJ6dXNwZWljaGVybi4gRGllIGVyaGFsdGVuZSBUYWJlbGxlIGhhdCBudW4gendlaSBTcGFsdGVuOiBKYWhyIHVuZCBBbnphaGwuIERlcyBXZWl0ZXJlbiBlcnN0ZWxsZW4gd2lyIHp3ZWkgd2VpdGVyZSBWYXJpYWJsZW4gKmF4KiB1bmQgKmF5KndlbGNoZSBiZWlkZSBlaW5lIExpc3RlIG1pdCBudXIgZWluZW0gQXR0cmlidXQgc2luZDog4oCcVGl0bGXigJ0uIE51biB2ZXJ3ZW5kZW4gd2lyICpwbG90X2x5KCkqIHVtIG1pdGhpbGZlIGRlciAqdHlwZSA9ICdzY2F0dGVyJyogdW5kICptb2RlID0gJ2xpbmVzJyogUGFyYW1ldGVyIGVpbiBMaW5pZW5kaWFncmFtbSB6dSBlcnN0ZWxsZW4uIEF1w59lcmRlbSBudXR6ZW4gd2lyIGRpZSAqbGF5b3V0KCkqIGZ1bmt0aW9uIHVtIGVpbmVuIFRpdGVsIHp1IGVyc3RlbGxlbiwgc293aWUgbWl0aGlsZmUgdW5zZXJlIGJlaWRlbiBWYXJpYWJsZW4gYXggdW5kIGF5IGRpZSBBY2hzZW4genUgYmVzY2hyaWZ0ZW4uDQoNCmBgYHtyIHBsb3QoQW1vdW50QnlZZWFyKSwgZWNobyA9IFRSVUUsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J21hcmt1cCcsIH0NCg0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgZ3JvdXBfYnkoWWVhcikgJT4lDQogIGRwbHlyOjpzdW1tYXJpemUoQW56YWhsID1uKCkpICU+JSBmaWx0ZXIoWWVhciE9J04vQScpJT4lZmlsdGVyKFllYXIhPTIwMjApICU+JSBmaWx0ZXIoWWVhciE9JzIwMTcnKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpDQoNCg0KZmlsdGVyZWQgPC0gZ3JvdXBlZCAlPiUgc2VsZWN0KFllYXIsQW56YWhsKQ0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJKYWhyIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJBbnphaGwiDQoNCikNCg0KZmlsdGVyZWQgJT4lDQpwbG90X2x5KHggPSB+WWVhciwgeSA9IH5BbnphaGwsIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMnLCBmaWxsID0gJ3RvemVyb3knICxjb2xvcnMgPSBteVBhbGV0dGUpICU+JSANCiAgbGF5b3V0KHRpdGxlPSJBbnphaGwgZGVyIFNwaWVsZXJlbGVhc2VzIHZvbiAxOTgwLTIwMTYiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgICkNCg0KYGBgDQoNCkJldHJhY2h0ZW4gd2lyIGVpbm1hbCBkYXMgZW50c3RhbmRlbmUgRGlhZ3JhbW0uIFp3aXNjaGVuIDE5ODAgdW5kIDE5OTMgc2luZCBoaWVyIGthdW0gVW50ZXJzY2hpZWRlIGZlc3R6dXN0ZWxsZW4gdW5kIGRpZSBTY2h3YW5rdW5nZW4ga8O2bm5lbiBhdWZncnVuZCBkZXIgZ2VyaW5nZW4gWmFobCBkZXIgVmVyw7ZmZmVudGxpY2h1bmdlbiAoendpc2NoZW4gMTQgdW5kIDQ5KSB2ZXJuYWNobMOkc3NpZ3Qgd2VyZGVuLiBBYiAxOTkzIGvDtm5uZW4gd2lyIGRhbm4gZWluIHN0ZXRpZ2VzIFdhY2hzdHVtIGZlc3RzdGVsbGVuIHdlbGNoZXMgMTk5OCB2b3JlcnN0IGRlbiBIw7ZjaHN0d2VydCBlcnJlaWNodC4gSW4gZGVuIEphaHJlbiAxOTk5IHVuZCAyMDAwIGdlaHQgZGllIEFuemFobCBlcnN0IGVpbm1hbCBsZWljaHQgenVyw7xjayBiZXZvciBzaWNoIGRlciBXZXJ0IGJpcyAyMDAyIHZvbiAzNDkgYXVmIDgyOSBtZWhyIGFscyB2ZXJkb3BwZWx0LiBCaXMgMjAwNCBpc3Qgd2llZGVydW0gZWluIGxlaWNodGVyIFLDvGNrZ2FuZyBmZXN0enVzdGVsbGVuIGF1ZiB3ZWxjaGVtIGVpbiBTdGV0aWdlcyBXYWNoc3R1bSB6dW0gSMO2Y2hzdHdlcnQgdm9uIDE0MjggKDIwMDgpIHNvd2llIDE0MzEgKDIwMDkpIGZvbGd0LiBEYW5hY2ggZm9sZ3QgZWluIGV4dHJlbWVyIHVuZCBtaXQgVW50ZXJicmVjaHVuZyB2b24gMjAxNCAoNTgyKSB1bmQgMjAxNSAoNjE0KSBzdGV0aWdlciBSw7xja2dhbmcgaW4gZGVuIFJlbGVhc2UgWmFobGVuIGF1ZiBlaW5lbiBTdGFuZCB2b24gMzQ0IGltIEphaHIgMjAxNi4NCg0KU2VoZW4gd2lyIHVucyBkaWVzZSBaYWhsZW4gZWlubWFsIGdlbmF1ZXIgYW4ga29tbXQgZGllIEZyYWdlIGF1ZiBXb3JhbiBkaWVzZSBFeHRyZW1lbiBaYWhsZW4gaW4gZGVuIFZlcsO2ZmZlbnRsaWNodW5nZW4genVyw7xja3p1ZsO8aHJlbiBzaW5kPyBBbiBkaWVzZW0gUHVua3QgZGVyIEFuYWx5c2Uga8O2bm5lbiB3aXIgbnVyIHNwZWt1bGllcmVuIGRpZSBTcGl0emVuIGvDtm5udGVuIGFsbGVyZGluZ3MgYW4gZGVuIFZlcsO2ZmZlbnRsaWNodW5nZW4gZ3Jvw59lciwgZGVuIE1hcmt0IGJlc3RpbW1lbmRlbiBQbGF0dGZvcm1lbiB3aWUgZGVyIFBTMi8zLCBkZXIgWGJveCB1bmQgZGVuIFBsYXR0Zm9ybWVuIHZvbiBOaW50ZW5kbyB3aWUgR2FtZWN1YmUgb2RlciBXaWkgenVyw7xja3p1ZsO8aHJlbiBzZWluLiBIaWVyenUgYWJlciBzcMOkdGVyIFttZWhyXSgjU2FsZXNQZXJQbGF0Zm9ybSkuDQoNCg0KIyMjIFJlbGVhc2VzIG5hY2ggVmVya2F1ZnN6YWhsZW4geyNWaWRlb0dhbWVSZWxlYXNlc1NhbGVzfQ0KDQpVbSBkZW0gendlaXRlbiBUZWlsIGRlciBGcmFnZXN0ZWxsdW5nIGF1ZiBkZW4gR3J1bmQgZ2VoZW4genUga8O2bm5lbiBtw7xzc2VuIHdpciBlcm5ldXQgZGllIERhdGVuIGRlciBUYWJlbGxlIHZnc2FsZXMgbWl0aGlsZmUgZGVyIEZ1bmt0aW9uICpncm91cF9ieShZZWFyKSogYW5oYW5kIGRlciBKYWhyZSBadXNhbW1lbmZhc3Nlbi4gTnVuIGVyaGFsdGVuIHdpciB3aWVkZXIgZGllIG5hY2ggZGVuIEphaHJlbiB6dXNhbW1lbmdlZmFzc3RlIFRhYmVsbGUgZGVyZW4gRWludHLDpGdlIHdpciBtaXQgZGVyIEZ1bmt0aW9uICAqZHBseXI6OnN1bW1hcml6ZShncl9zdW0gPSBzdW0oR2xvYmFsX1NhbGVzKSkqIHp1c2FtbWVuZmFzc2VuLiBEZW0gQXVmbWVya3NhbWVuIExlc2VyIHdpcmQgYXVmZmFsbGVuIGRhcyBoaWVyIGVpbiBrbGVpbmVyIGFiZXIgZmVpbmVyIFVudGVyc2NoaWVkIHp1bSB2b3JoZXJpZ2VuIEF1ZnJ1ZiBiZXN0ZWh0LiBTdGF0dCAqQW56YWhsID1uKCkqIG51dHplbiB3aXIgaGllciAqZ3Jfc3VtID0gc3VtKEdsb2JhbF9TYWxlcykqLiBEaWVzZSBGdW5rdGlvbiBzdW1taWVydCBhbGxlIFdlcnRlIGRlciBTcGFsdGUgR2xvYmFsX1NhbGVzIGF1ZiB1bmQgc3BlaWNoZXJ0IGRlbiBkZW4gV2VydCBpbiBkaWUgU3BhbHRlICpncl9zdW0qLiBBdWZncnVuZCBkZXIgZsO8ciBkaWVzZSBhbmFseXNlIHdlaXRlcmhpbiBGZWhsZXJoYWZ0ZW4gRGF0ZW4gdmVyd2VuZGVuIHdpciBlcm5ldXQgZGllIEZ1bmt0aW9uICpmaWx0ZXIoKSogdW0gYWxsZSBmZWhsZW5kZW4gSmFocmVzZWludHLDpGdlIHNvd2llIGRpZSBKYWhyZSAyMDIwIHVuZCAyMDE3IGhlcmF1c3p1ZmlsdGVybi4gIERpZXNlIERhdGVuIHNwZWljaGVybiB3aXIgd2llZGVyIGFscyAqZGF0YS5mcmFtZSogaW4gZGVyIFZhcmlhYmxlICpncm91cGVkKiBhYi4gSW0gZm9sZ2VuZGVuIHZlcndlbmRlbiB3aXIgZWJlbmplbmVzIGRhdGEuZnJhbWUgdW0gbnVyIGRpZSBFaW50csOkZ2UgSmFociB1bmQgKmdyX3N1bSogenUgc2VsZWt0aWVyZW4gdW5kIGluIGRlciBWYXJpYWJsZSAqZmlsdGVyZWQqIGFienVzcGVpY2hlcm4uIERpZSBlcmhhbHRlbmUgVGFiZWxsZSBoYXQgbnVuIHp3ZWkgU3BhbHRlbjogSmFociB1bmQgKmdyX3N1bSouIERlc3dlaXRlcmVuIGVyc3RlbGxlbiB3aXIgZXJuZXV0IGRpZSBWYXJpYWJsZW4gKmF4KiB1bmQgKmF5Ki4gTnVuIHZlcndlbmRlbiB3aXIgKnBsb3RfbHkoKSogdW0gbWl0aGlsZmUgZGVyICp0eXBlID0gJ3NjYXR0ZXInKiB1bmQgKm1vZGUgPSAnbGluZXMnKiBQYXJhbWV0ZXIgZWluIExpbmllbmRpYWdyYW1tIHp1IGVyc3RlbGxlbi4gQXXDn2VyZGVtIG51dHplbiB3aXIgZGllICpsYXlvdXQoKSogZnVua3Rpb24gdW0gZWluZW4gdGl0ZWwgenUgZXJzdGVsbGVuLCBzb3dpZSBtaXRoaWxmZSB1bnNlcmUgYmVpZGVuIFZhcmlhYmxlbiBheCB1bmQgYXkgZGllIEFjaHNlbiB6dSBiZXNjaHJpZnRlbi4NCg0KYGBge3IgcGxvdChHYW1lU2FsZXNCeVllYXIpLCBpbmNsdWRlPVRSVUUsIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQoNCmdyb3VwZWQgPC0gdmdzYWxlcyAgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogIGdyb3VwX2J5KFllYXIpICU+JQ0KICBkcGx5cjo6c3VtbWFyaXplKGdyX3N1bSA9IHN1bShHbG9iYWxfU2FsZXMpKSAlPiUgZmlsdGVyKFllYXIhPSdOL0EnKSU+JWZpbHRlcihZZWFyIT0yMDIwKSAlPiUgZmlsdGVyKFllYXIhPScyMDE3JykgJT4lDQogIGFzLmRhdGEuZnJhbWUoKQ0KDQoNCmZpbHRlcmVkIDwtIGdyb3VwZWQgJT4lIHNlbGVjdChZZWFyLGdyX3N1bSkNCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiSmFociINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiIFZlcmvDpHVmZSBwcm8gSmFociAoaW4gbWlvKSINCg0KKQ0KDQpmaWx0ZXJlZCAlPiUNCnBsb3RfbHkoeCA9IH5ZZWFyLCB5ID0gfmdyX3N1bSwgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdsaW5lcycsIGZpbGwgPSAndG96ZXJveScgLGNvbG9ycyA9IG15UGFsZXR0ZSkgJT4lIA0KICBsYXlvdXQodGl0bGU9IlZpZGVvc3BpZWx2ZXJrw6R1ZmUgdm9uIDE5ODAtMjAxNiIsDQogICAgICAgICB4YXhpcyA9IGF4LA0KICAgICAgICAgeWF4aXMgPSBheQ0KICAgICAgICAgKQ0KDQpgYGANCg0KQmV0cmFjaHRlbiB3aXIgbnVuIGRhcyBlbnRzdGFuZGVuZSBEaWFncmFtbSBmw6RsbHQgdW5zIHp1ZXJzdCBhdWYsIGRhc3MgZXMgZGVtIHZvcmhlcmlnZW4gcmVjaHQgw6RobmxpY2ggc2llaHQuIERpZXMgaXN0IGthdW0gdmVyd3VuZGVybGljaCB1bmQgc3RlbGx0IGtlaW5lbiBuZW5uZW5zd2VydGVuIFdpc3NlbnNnZXdpbm4gZGEuIERlciB3b2hsIE5lbm5lc3dlcnRlc3RlIHVudGVyc2NoaWVkIGlzdCBkYXMgRmVobGVuIGRlcyBBbnN0aWVncywgd2VsY2hlciBpbiBkZXIgQW56YWhsIGRlciBHYW1lcmVsZWFzZXMgenVtIEphaHIgMjAxNSBmZXN0enVzdGVsbGVuIHdhci4gRHVyY2ggZGVuIGRpcmVrdGVuIFZlcmdsZWljaCBpc3QgZGllcyBhbGxlcmRpbmdzIGVpbiBndXRlciBaZWl0cHVua3QgdW0gdW5zIG1pdCB1bnNlcmVyIFp3ZWl0ZW4gVGhlc2UgYXVzZWluYW5kZXJ6dXNldHplbi4gKiJXZXJkZW4gaGV1dHp1dGFnZSBtZWhyIFNwaWVsZSBSZWxlYXN0IHVuZCBWZXJrYXVmdCBhbHMgbm9jaCAxOTgwPyIqLiBEaWVzZSBzZWhlbiB3aXIgYXVmamVkZW5mYWxsIGJlc3TDpHRpZ3Qgb2J3b2hsIEZlc3R6dXN0ZWxsZW4gaXN0LCBkYXNzIGRpZSBiZXN0ZW4gSmFocmUgc293b2hsIGluIHZlcmvDpHVmZW4gYWxzIGF1Y2ggaW4gZGVyIEFuemFobCBkaWUgSmFocmUgMjAwOCB1bmQgMjAwOSB3YXJlbi4gRGllcyBXaXJmdCBuYXTDvHJsaWNoIGRpZSBGcmFnZSBhdWYgd2FzIGRlciBHcnVuZCBmw7xyIGRpZXNlbiBWZXJsYXVmIGlzdCB1bmQgd8OkcmUgZWluIEludGVyZXNzYW50ZXIgYW5zYXR6IGbDvHIgZWluZSBbd2VpdGVyZSBBcmJlaXRdKCNBdXNibGlja0luRGllWnVrdW5mdCkuDQoNCiMjIyBWZXJrYXVmc3phaGxlbiBwcm8gU3BpZWwgDQoNCkRpZSBGcmFnZSBkaWUgV2lyIGFsbGVyZGluZ3MgYmVhbnR3b3J0ZW4ga8O2bm5lbiBpc3QgKiJXZXJkZW4gbmV1ZXJlIFNwaWVsZSBhdXRvbWF0aXNjaCBtZWhyIEdla2F1ZnQ/IiouIERhZsO8ciBrb21iaW5pZXJlbiB3aXIgZGllIGJlaWRlbiBiZXJlaXRzIFZlcndlbmRldGVuIGFuc8OkdHplLiANCldpciBmYXNzZW4gd2llZGVyIGRpZSBkYXRlbiBtaXRoaWxmZSB2b24gKmdyb3VwX2J5KFllYXIpKiBhbmhhbmQgZGVyIEphaHJlIFp1c2FtbWVuLiBEaWUgZXJoYWx0ZW5lIFRhYmVsbGUgZmFzc2VuIHdpciB3aWVkZXIgbWl0ICAqZHBseXI6OnN1bW1hcml6ZShncl9zdW0gPSBzdW0oR2xvYmFsX1NhbGVzKSkqIHp1c2FtbWVuLiBEaWVzbWFsIG51dHplbiB3aXIgamVkb2NoIGVpbmUga29tYmluYXRpb24gYXVzICpzdW0oR2xvYmFsX1NhbGVzKSogdW5kICpuKCkqLiBXaXIgYWRkaWVyZW4gZGllIFNwYWx0ZSAqR2xvYmFsX1NhbGVzKiwgdGVpbGVuIGRpZXMgZHVyY2ggZGllIEFuemFobCBkZXIgRWludHLDpGdlIHVuZCBzcGVpY2hlcm4gZGVuIFdlcnQgaW4gZGllIFNwYWx0ZSAqZ2FtZXNhbGVzKiAoKmdhbWVzYWxlcyA9IHN1bShHbG9iYWxfU2FsZXMpL24oKSopLiBEYW5hY2ggZmlsdGVybiB3aXIgZGllIERhdGVuIGVybmV1dCB1bmQgc3BlaWNoZXJuIHNpZSBhbHMgKmRhdGEuZnJhbWUqIGluIGdyb3VwZWQgYWIuIERpZXNtYWwgc2VsZWt0aWVyZW4gd2llIGRpZSBFaW50csOkZ2UgZGVyIFNwYWx0ZSBKYWhyIHNvd2llICpnYW1lc2FsZXMqIHVuZCBzcGVpY2hlcm4gc2llIGluIGRlciBWYXJpYWJsZSAqZmlsdGVyZWQqIGFiLiBadWxldHp0IGVyc3RlbGxlbiB3aXIgZXJuZXV0IGRpZSBWYXJpYWJsZW4gKmF4KiB1bmQgKmF5KiB1bmQgdmVyd2VuZGVuICpwbG90X2x5KCkqIHVtIG1pdGhpbGZlIGRlciAqdHlwZSA9ICdzY2F0dGVyJyogdW5kICptb2RlID0gJ2xpbmVzJyogUGFyYW1ldGVyIGVpbiBMaW5pZW5kaWFncmFtbSB6dSBlcnN0ZWxsZW4gc293aWUgZGllICpsYXlvdXQoKSogZnVua3Rpb24gdW0gZWluZW4gdGl0ZWwgenUgZXJzdGVsbGVuIHVuZCBtaXRoaWxmZSB1bnNlcmUgYmVpZGVuIFZhcmlhYmxlbiBheCB1bmQgYXkgZGllIEFjaHNlbiB6dSBiZXNjaHJpZnRlbi4NCg0KYGBge3IgcGxvdChTYWxlc2J5R2FtZUJ5WWVhciksIGluY2x1ZGU9VFJVRSwgZWNobyA9IFRSVUUsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J21hcmt1cCcsIH0NCg0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgZ3JvdXBfYnkoWWVhcikgJT4lDQogIGRwbHlyOjpzdW1tYXJpemUoZ2FtZXNhbGVzID0gc3VtKEdsb2JhbF9TYWxlcykvbigpKSAlPiUgZmlsdGVyKFllYXIhPSdOL0EnKSU+JWZpbHRlcihZZWFyIT0yMDIwKSAlPiUgZmlsdGVyKFllYXIhPScyMDE3JykgJT4lDQogIGFzLmRhdGEuZnJhbWUoKQ0KDQoNCmZpbHRlcmVkIDwtIGdyb3VwZWQgJT4lIHNlbGVjdChZZWFyLGdhbWVzYWxlcykNCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiSmFociINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiVmVya8OkdWZlIHBybyBTcGllbCINCg0KKQ0KDQpmaWx0ZXJlZCAlPiUNCnBsb3RfbHkoeCA9IH5ZZWFyLCB5ID0gfmdhbWVzYWxlcywgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdsaW5lcycsIGZpbGwgPSAndG96ZXJveScgLGNvbG9ycyA9IG15UGFsZXR0ZSkgJT4lIA0KICBsYXlvdXQodGl0bGU9IlZpZGVvc3BpZWx2ZXJrw6R1ZmUgcHJvIFNwaWVsIHZvbiAxOTgwLTIwMTYiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgICkNCg0KYGBgDQpTYWhlbiBzaWNoIGRpZSBiZWlkZW4gRGlhZ3JhbW1lIGbDvHIgQW56YWhsIHVuZCBWZXJrYXVmc3phaGxlbiBub2NoIHJlY2h0IMOkaG5saWNoIHN0ZWxsdCBzaWNoIGhpZXIgZWluIGRldXRsaWNoIHVudGVyc2NoaWVkbGljaGVyIFZlcmxhdWYgZGEuIElzdCBkZXIgV2VydCB6d2lzY2hlbiAxOTgwICgxLjI2KSB1bmQgMTk4MyAoMC45OCkgbm9jaCByZWxhdGl2IGdlcmluZyBzdGVpZ3QgZGllc2VyIE1hc3NpdiBmw7xyIGRpZSBKYWhyZSAxOTg0KDMuNTkpIHVuZCAxOTg1KDMuODUpIGJldm9yIGVyIDE5ODYoMS43NikgdW5kIDE5ODcoMS4zNSkgd2llZGVyIGFic2lua3QuIEdlbmF1c28gc2NobmVsbCB3aWUgZGVyIHdlcnQgYWJnZXN1bmtlbiBpc3Qgc3RlaWd0IGVyIGFsbGVyZGluZ3MgYXVjaCB3aWVkZXIgYXVmIDMuMTQoMTk4OCkgYmV2b3IgZXIgMTk4OSBkZW4gSMO2Y2hzdHN0YW5kIG1pdCA0LjMyIGVycmVpY2h0LiBEYW5hY2ggc2lua3QgZGVyIHdpZWRlciBhYiB1bSBzaWNoIG5hY2ggZWluZW0ga3VyemVuIGF1c3NjaGxhZyAxOTkyIGluIGRlbiBKYWhyZW4gYmlzIDIwMTQgYXVmIGVpbmVuIHJlbGF0aXYgc3RldGlnZW4gV2VydCBad2lzY2hlbiAwLjUgdW5kIDAuNyBlaW56dXBlbmRlbG4gZXJzdCAyMDE1IHVuZCAyMDE2IHNpbmt0IGRpZXNlciB1bnRlciAwLjUuIERpZXNlIEV4dHJlbWVuIGF1c3NjaGzDpGdlIGluIGRlbiBGcsO8aGVyZW4gSmFocmVuIGxhc3NlbiBzaWNoIG1pdCBkZXIgR2VyaW5nZW4gYW56YWhsIGRlciBTcGllbGUgZXJrbMOkcmVuLiBFaW56ZWxuZSBndXRlIGxhdWZlbmRlIFNwaWVsZSBtYWNoZW4gaGllciBub2NoIGVpbmVuIEdyb8OfdGVpbCBkZXMgTWFya3RzIGF1cyB3b2hpbmdlZ2VuIHNpY2ggbmV1ZXJlIHNwaWVsZSwgc293b2hsIGdlZ2VuIGVpbmUgR3Jvw596YWhsIHZvbiBiZXJlaXRzIGV0YWJsaWVydGVuIFNwaWVsZSBhbHMgYXVjaCBlaW5lIGdyb8OfZSBBbnphaGwgbmV1ZXIgUmVsZWFzZXMsIGR1cmNoc2V0emVuIG3DvHNzZW4uDQoNCiMjIHstfQ0KDQoqKioNCg0KIyBQbGF0Zm9ybSBBbmFseXNlIHsjUGxhdGZvcm1hbmFseXNlfQ0KDQpgYGB7ciBub3Bsb3QsIGVjaG8gPSBGQUxTRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgaW5jbHVkZSA9RkFMU0UsfQ0KdmdzYWxlcyAlPiUgDQogIHBsb3RfbHkoDQogICAgeD1+UGxhdGZvcm0sDQogICAgc3Ryb2tlPUkoImJsYWNrIiksDQogICAgbmFtZT0iQW1vdW50IGJ5IFBsYXRmb3JtIikgJT4lDQogIGxheW91dCgNCiAgICB0aXRsZT0iQW1vdW50IGJ5IFBsYXRmb3JtIikNCnZnc2FsZXMgJT4lIA0KICBwbG90X2x5ICU+JSANCiAgYWRkX2JveHBsb3QoDQogICAgeD1+UGxhdGZvcm0sDQogICAgc3Ryb2tlPUkoImJsYWNrIiksDQogICAgbmFtZT0iQW1vdW50IGJ5IFBsYXRmb3JtIikgJT4lIA0KICBsYXlvdXQoDQogICAgdGl0bGU9IkFtb3VudCBieSBQbGF0Zm9ybSIpDQoNCnZnc2FsZXMgJT4lIA0KICBwbG90X2x5KCkgJT4lIA0KICBhZGRfYmFycygNCiAgICB4PX5HbG9iYWxfU2FsZXMsDQogICAgeT1+UGxhdGZvcm0sDQogICAgbmFtZT0iU2FsZXMgYnkgUGxhdGZvcm0gKGluIG1pbykiKSAlPiUgDQogIGxheW91dCgNCiAgICB0aXRsZT0iU2FsZXMgYnkgUGxhdGZvcm0gKGluIG1pbykiKQ0KDQpgYGANCg0KVmllZGVvc3BpZWxlIGdpYnQgZXMgaW4gZGVuIFVudGVyc2NoaWVkbGljaHN0ZW4gRmFyYmVuIHVuZCBGb3JtZW4uIFdhcyBTaWUgamVkb2NoIGFsbGUgZ2VtZWluc2FtIGhhYmVuIGlzdCwgZGFzcyBzaWUgYXVmIGVpbmVtIG1lZGl1bSBHZXNwaWVsdCB3ZXJkZW4uIFNlaSBlcyBTb255cyBQbGF5c3RhdGlvbiwgTWljcm9zb2Z0cyB4Qm94LCBOaW50ZW5kb3MgU3BpZWxla29uc29sZW4gd2llIGRpZSBXaWkgb2RlciBkZXIgZWluZmFjaGUgZGVza3RvcCBQQy4gRGllIEZyYWdlIGRpZSBTaWNoIGplZGVyIEZhbiBqZWRvY2ggc2Nob25tYWwgZ2VzdGVsbHQgaGF0IHVuZCDDvGJlciBkaWUgaMOkdWZpZyBkaXNrdXRpZXJ0IHdpcmQgaXN0IHdlbGNoZSBpc3QgZGllIEJlc3RlPyBEYSBkaWVzIGltbWVyIGltIEF1Z2UgZGVzIEJldHJhY2h0ZXJzIGxpZWd0IHZlcnN1Y2hlbiB3aXIgenVtaW5kZXN0ZW5zIHp1IGtsw6RyZW4gKldlbGNoZSBQbGF0Zm9ybSBpc3QgZGllIGJlc3RlIGluIEFuemFobCB2ZXJrw6R1ZmVuPyBXZWxjaGUgaW4gQW56YWhsIGRlciBHYW1lIFJlbGVhc2VzPyouIFp1bSBiZWFudHdvcnRlbiBkaWVzZXIgRnJhZ2UgaXN0IGRlciBWb3JoYW5kZW5lIERhdGVuc2F0eiBuaWNodCBnYW56IG9wdGltYWwgYWJlciBoaWVyenUgd2VpdGVyZXMgaW0gW0Zheml0XSgjQXVmZ2V0cmV0ZW5lUHJvYmxlbWUpLg0KDQoNCiMjIFBsYXRmb3JtYW5hbHlzZSBHbG9iYWwgey50YWJzZXR9DQoNCiMjIyBuYWNoIEFuemFobA0KDQpVbSBzaWNoIGVpbmVuIGd1dGVuIMOcYmVyYmxpY2sgw7xiZXIgZGllIFJhbmtpbmdzIGRlciBQbGF0dGZvcm1lbiB6dSB2ZXJzY2hhZmZlbiBudXR6ZW4gd2lyIGhpZXIgZWluIFBhcmV0b2RpYWdyYW1tLiBEaWVzIHNpbmQgbmFjaCBkZXIgR3LDtsOfZSBkZXIgV2VydGUgc29ydGllcnRlIFPDpHVsZW5kaWFncmFtbWUuIFp1bSBFcnN0ZWxsZW4gZGVzIERpYWdyYW1tcyBicmF1Y2hlbiB3aXIgenVlcnN0IGVpbm1hbCB3aWVkZXIgdW5zZXJlbiBEYXRlbnNhdHogZGVuIHdpciBkaWVzbWFsIG1pdGhpbGZlIGRlcyAqZ3JvdXBfYnkqIEJlZmVobHMgYW5oYW5kIGRlciAqUGxhdGZvcm0qIGdydXBwaWVyZW4uIERhbmFjaCBudXR6ZW4gd2lyIGVybmV1dCAqc3VtbWFyaXplKEFuemFobCA9bigpKiB1bSBkaWUgRWludHLDpGdlIGFienV6w6RobGVuIHVuZCBkZW4gd2VydCBhbHMgQW56YWhsIGFienVzcGVpY2hlcm4uIFVtIGRpZSBFaW50csOkZ2UgZGVyIEFuemFobCBuYWNoIHp1IHNvcnRpZXJlbiBudXR6ZW4gd2lyIHp1ZXJzdCBkZW4gQmVmZWhsICpncm91cGVkW29yZGVyKGdyb3VwZWRcJEFuemFobCksZGVjcmVhc2luZyA9IEZBTFNFXSogdW5kIHdlaXNlbiBkYXMgRXJnZWJuaXMgZGVyIG5ldWVuIFRhYmVsbGUgKk9yZGVyZWQqIHp1LiBEaWVzZXIgQmVmZWhsIHNpZWh0IHJlbGF0aXYga29tcGxleCBhdXMgbMOkc3N0IHNpY2ggamVkb2NoIHJlY2h0IGVpbmZhY2ggYXVmZHLDtnNlbG4uIE9yZGVyIHNvcnRpZXJ0IGRpZSBUYWJlbGxlIG5hY2ggZGVyIGdlZ2ViZW5lbiBTcGFsdGUgdW5kIGRlciBQYXJhbWV0ZXIgKmRlY3JlYXNpbmcgPSogZ2lidCBhbiBvYiBkZXIgZ3LDtsOfdGUgV2VydCBhbSBBbmZhbmcgb2RlciBFbmRlIHN0ZWhlbiBzb2xsLiBEYXMgRG9sbGFyIFplaWNoZW4gc2VsZWt0aWVydCBoaWVyYmVpIGRpZSBTcGFsdGUgbWl0IGRlbSBkYWhpbnRlcnN0ZWhlbmRlbiBOYW1lIGF1cyBkZXIgdm9yaGVyIHN0ZWhlbmRlbiBUYWJlbGxlIGdldHJldSBuYWNoIGRlbSBTY2hlbWEgKlRhYmVsbGVcJFNwYWx0ZSouIERhbmFjaCBtw7xzc2VuIHdpciBub2NoIGRpZSBTcGFsdGUgKlBsYXRmb3JtKiBhbHMgZmFrdG9yIGVpbmxlc2VuIHdlbGNoZXMgd2lyIG1pdCBkZW0gQmVmZWhsICphc19mYWN0b3Iob3JkZXJlZFwkUGxhdGZvcm0pKiB0dW4uIERhbmFjaCBlcnN0ZWxsZW4gd2lyIHVuc2VyZSBiZWlkZW4gVmFyaWFibGVuIGF4IHVuZCBheSB6dXIgQWNoc2VuYmVzY2hyaWZ0dW5nLiBOdW4ga29tbWVuIHdpciB6dXIgZWlnZW50bGljaGVuIERpYWdyYW1tZXJzdGVsbHVuZy4gV2lyIGdlYmVuIGRpZSBUYWJlbGxlICpvcmRlcmVkKiB3ZWl0ZXIgYW4gKnBsb3RfbHkoKSogdW5kIG51dHplbiAqYWRkX2JhcnMqIHVtIGVpbiBCYWxrZW5kaWFncmFtbSB6dSBlcnN0ZWxsZW4uIERlciB1bnRlcnNjaGllZCB6d2lzY2hlbiBCYWxrZW4gdW5kIFBhcmV0b2RpYWdyYW1tIGxpZWd0IGhpZXJiZWkgaW4gZGVyIFBhcmFtZXRlcsO8YmVyZ2FiZS4gU2NoYXVlbiB3aXIgdW5zIGRpZSByZWxldmFudGVuIFRlaWxlIGVpbm1hbCBnZW5hdWVyIGFuLiBEZXIgaW50ZXJlc3NhbnRlIFRlaWwgcGFzc2llcnQgaGllcmJlaSBiZWkgZGVyIHp1d2Vpc3VuZyBkZXIgWC1BY2hzZSB1bmQgaGllciBzZWhlbiB3aXIgYXVjaCBkZW4gR3J1bmQgZsO8ciB1bnNlcmUgdm9yaGVyaWdlIHVtd2FuZGx1bmcgZGVyIFNwYWx0ZSBQbGF0Zm9ybSB6dSBlaW5lbSBmYWt0b3IuICp4PX5mY3RfcmVvcmRlcihQbGF0Zm9ybSxBbnphaGwsIC5kZXNjPSJ0cnVlIikseT1+QW56YWhsKiBXaXIgbnV0emVuIGRlbiBCZWZlaGVsICpmY3RfcmVvcmRlcigpKiB1bSBkaWUgUGxhdGZvcm1lbiBuYWNoIGRlciBBbnphaGwgc29ydGllcnQgaGVyIGFuenVvcmRuZW4uIERlciBlcnN0ZSBQYXJhbWV0ZXIgaXN0IGhpZXJiZWkgZGllIHp1IHNvcnRpZXJlbmRlIFNwYWx0ZSwgZGVyIHp3ZWl0ZSBkaWUgbmFjaCBkZXIgc29ydGllcnQgd2VyZGVuIHNvbGwuIERlciBQYXJhbWV0ZXIgLmRlc2Mgc3RlaHQgZGVzY2VuZGluZyB1bmQgYmVzdGltbXQgd2llIHNvcnRpZXJ0IHdlcmRlbiBzb2xsLCBpbiB1bnNlcmVtIGZhbGwgZGVyIGdyw7bDn3RlIFdlcnQgenVlcnN0LiBadSBndXRlciBsZXR6dCBnZWJlbiB3aXIgZGVtIERpYWdyYW1tIG5vY2ggZWluZW4gTmFtZW4sIHdlaXNlbiBkaWUgRmFyYnBhbGV0dGUgenUgdW5kIHNldHplbiBkYXMgTGF5b3V0IG1pdCBkZW0gVGl0ZWwgc293aWUgdW5zZXJlbiBiZWlkZW4gQWNoc2VuYmVzY2hyaWZ0dW5nZW4uDQoNCmBgYHtyIHBsb3QsIGVjaG8gPSBUUlVFLG1lc3NhZ2U9RkFMU0UscmVzdWx0cz0nbWFya3VwJyx9DQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoUGxhdGZvcm0pICU+JSANCiAgc3VtbWFyaXplKEFuemFobCA9bigpKSANCg0Kb3JkZXJlZCA8LSBncm91cGVkW29yZGVyKGdyb3VwZWQkQW56YWhsKSwgZGVjcmVhc2luZyA9IEZBTFNFXQ0Kb3JkZXJlZCRQbGF0Zm9ybSA8LSBhc19mYWN0b3Iob3JkZXJlZCRQbGF0Zm9ybSkNCg0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJQbGF0Zm9ybSINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiQW56YWhsIg0KKQ0Kb3JkZXJlZCU+JQ0KICBwbG90X2x5KCkgJT4lIA0KICBhZGRfYmFycyh4PX5mY3RfcmVvcmRlcihQbGF0Zm9ybSxBbnphaGwsIC5kZXNjPSJ0cnVlIiksDQogICAgICAgICAgIHk9fkFuemFobCwNCiAgICAgICAgICAgbmFtZT0iU3BpZWxlYW56YWhsIHBybyBQbGF0Zm9ybSIgLGNvbG9ycyA9IG15UGFsZXR0ZSkgJT4lIA0KICBsYXlvdXQodGl0bGU9IlNwaWVsZWFuemFobCBwcm8gUGxhdGZvcm0iLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgIA0KICAgICAgICAgKQ0KYGBgDQoNCkJlaW0gQmV0cmFjaHRlbiBkZXMgRGlhZ3JhbW1zIGVya2VubmVuIHdpciBkYXMgd2VkZXIgZ2FueiBhbHRlIG5vY2ggZ2FueiBuZXVlIFBsYXRmb3JtZW4gZGllIE5hc2Ugdm9ybmUgaGFiZW4uIEFuIGRlbiBlcnN0ZW4gYmVpZGVuIFN0ZWxsZW4gdW5kIHdlaXQgYWJnZXNjaGxhZ2VuIHZvbSBSZXN0IGRlciBQbGF0Zm9ybWVuIGZpbmRlbiBzaWNoIGhpZXIgZGVyIERTIHZvbiBOaW50ZW5kbyAoMjE2MykgdW5kIGRpZSBQbGF5c3RhdGlvbiAyIHZvbiBTb255ICgyMTYxKS4gRGllcyBpc3Qgd2VpdGVyIG5pY2h0IFZlcnd1bmRlcmxpY2ggZGEgYmVpZGUgYXVjaCBkaWUgS29uc29sZW4gc2luZCBkaWUgc2ljaCBbV2VsdHdlaXQgYW0gYmVzdGVuIHZlcmthdWZ0IGhhYmVuXShodHRwczovL2RlLnN0YXRpc3RhLmNvbS9zdGF0aXN0aWsvZGF0ZW4vc3R1ZGllLzE2MDU0OS91bWZyYWdlL2FuemFobC1kZXItd2VsdHdlaXQtdmVya2F1ZnRlbi1zcGllbGtvbnNvbGVuLW5hY2gta29uc29sZW50eXBlbi8pLiBFaW4gd2VpdGVyZXIgR3J1bmQgZsO8ciBkZXJlbiBob2hlIFNwaWVsZWFuemFobCBpc3QgdmVybXV0bGljaCBhdWNoIGRlcmVuIFN0ZWxsdW5nIGFscyBQbGF0emhpcnNjaGUgaW0gS29uc29sZW4tIGJ6dy4gSGFuZGhlbGRtYXJrdC4gV2VpdGVyaGluIGvDtm5uZW4gd2lyIGVya2VubmVuIGRhcyBlcyBtZWlzdCBkaWUgw6RsdGVyZSBHZW5lcmF0aW9uZW4gZWluZXIgS29uc29sZSBzaW5kIGRpZSBtZWhyIFNwaWVsZSBoYWJlbi4gRGllIFBsYXlzYXRhdGlvbiAyIGhhdCBiZWlzcGllbHN3ZWlzZSBtZWhyIFNwaWVsZSBhbHMgUFMzIHVuZCBQUzQsIGRpZSBYYm9YMzYwIG1laHIgYWxzIGRpZSB4Qm94T25lIHVuZCBkZXIgRFMgbWVociBhbHMgZGVyIDNEUy4gRGllcyBzY2hlaW50IGplZG9jaCBuaWNodCBhdWYgZGllIGVyc3RlIEdlbmVyYXRpb24genV6dXRyZWZmZW4uIERpZSBQbGF5c3RhdGlvbiBoYXQgbWVociB2ZXJrw6R1ZmUgYWxzIGRpZSBQUzQgYWJlciB3ZW5pZ2VyIGFscyBQUzMgdW5kIFBTMi4gRGllIFhib3ggbWVociBhbHMgZGllIFhib3hPbmUgYWJlciB3ZW5pZ2VyIGFscyBkaWUgWGJveDM2MC4NCg0KDQojIyMgbmFjaCBWZXJrYXVmc3phaGxlbg0KDQpTY2hhdWVuIHdpciB1bnMgbnVuIGRpZSBWZXJrYXVmc3phaGxlbiBkZXIgU3BpZWxlIGRlciBlaW56ZWxuZW4gUGxhdGZvcm1lbiBhbi4gV2lyIHZlcndlbmRlbiBoaWVyIHdpZWRlciBlaW4gUGFyZXRvZGlhZ3JhbW0gdW5kIGdlaGVuIMOkaG5saWNoIGRlcyB2b3JoZXJpZ2VuIERpYWdyYW1tcyB2b3IuIFp1ZXJzdCBudXR6ZW4gd2lyIHdpZWRlciBkaWUgKmdyb3VwX2J5KiBGdW5rdGlvbiB1bSBuYWNoIGRlbiBQbGF0Zm9ybWVuIHp1IGdydXBwaWVyZW4uIERhIHdpciBudW4gYWJlciBkaWUgVmVya2F1ZnN6YWhsZW4gYmV0cmFjaHRlbiB3b2xsZW4gbnV0emVuIHdpciAqc3VtbWFyaXplKCkqIGF1ZiBkaWUgKkdsb2JhbF9TYWxlcyogU3BhbHRlLiBOdW4gbnV0emVuIHdpciBkaWUgKnJlbmFtZSgpKiBmdW5rdGlvbiB1bSBkaWUgc28gZW50c3RhbmRlbmUgU3BhbGUgKnN1bShHbG9iYWxfU2FsZXMpKiBpbiAqR2xvYmFsX1NhbGVzKiB1bXp1YmVuZW5uZW4uIERpZXMgaGF0IGtlaW5lbiB3ZWl0ZXJlbiBOdXR6ZW4gYXXDn2VyIHVucyBpbSBzcMOkdGVyZW4gVmVybGF1ZiBkaWUgUmVmZXJlbnppZXJ1bmcgZGVyIFNwYWx0ZSBlaW5mYWNoZXIgenUgbWFjaGVuLiBVbSBzcMOkdGVyIG5hY2ggZGllc2VyIG5ldSBlcnN0ZWxsdGVuIFNwYWx0ZSBzb3J0aWVyZW4genUga8O2bm5lbiBtw7xzc2VuIHdpciBkaWVzZSB6dWVyc3QgaW4gZWluZW4gVmVjdG9yIHVtd2FuZGVsbi4gRGllcyB0dW4gd2lyIG1pdCBkZW0gQmVmZWhsICpncm91cGVkXCRHbG9iYWxfU2FsZXM8LWFzX3ZlY3Rvcihncm91cGVkXCRHbG9iYWxfU2FsZXMpKi4gTnVuIGvDtm5uZW4gd2lyIGRpZSBUYWJlbGxlIHNvcnRpZXJlbiB1bmQgaW4gZGVyIFZhcmlhYmxlIG9yZGVyZWQgYWJzcGVpY2hlcm4gDQoqb3JkZXJlZCA8LSBncm91cGVkW29yZGVyKGdyb3VwZWRcJEdsb2JhbF9TYWxlcyksIGRlY3JlYXNpbmcgPSBGQUxTRV0qLiBBbHMgbGV0enRlbiBTY2hyaXR0IGJldm9yIGVzIGFuIGRpZSBlcnN0ZWxsdW5nIGRlcyBEaWFncmFtbXMgZ2VodCB3YW5kZWxuIHdpciBub2NoIGRpZSBTcGFsdGUgUGxhdGZvcm0gaW4gZWluZW4gRmFjdG9yIHVtICpvcmRlcmVkJFBsYXRmb3JtIDwtIGFzX2ZhY3RvcihvcmRlcmVkXCRQbGF0Zm9ybSkqIHVuZCBlcnN0ZWxsZW4gZXJuZXV0IHVuc2VyZSBBY2hzZW5iZXNjaHJpZnR1bmdlbiBheCB1bmQgYXkuIFp1ciBlcnN0ZWxsdW5nIGRlcyBEaWFncmFtbXMgw7xiZXJnZWJlbiB3aXIgdW5zZXJlICpvcmRlcmVkKiBUYWJlbGxlIGFuIGRpZSAqcGxvdF9seSgpKiBmdW5rdGlvbiB1bmQgbnV0emVuICphZGRfYmFycyogdW0gZWluIEJhbGtlbmRpYWdyYW1tIHp1IGVyc3RlbGxlbi4gSGllciB2ZXJ3ZW5kZW4gd2lyIHdpZWRlciBkaWUgUGFyYW1ldGVyICp4PX5mY3RfcmVvcmRlcihQbGF0Zm9ybSxHbG9iYWxfU2FsZXMsIC5kZXNjPSJ0cnVlIiksIHk9fkdsb2JhbF9TYWxlcyogdW0gZGVuIHggd2VydCwgYWxzbyBkaWUgUGxhdGZvcm1lbiBuYWNoIGRlbiBHbG9iYWwgU2FsZXMgenUgc29ydGllcmVuIGJldm9yIHdpciBkZW4gbmFtZW4gdW5kIGRpZSBGYXJiZSBkZXMgRGlhZ3JhbW1zIHNldHplbi4gWnUgZ3V0ZXIgTGV0enQgYmVudXR6ZW4gd2lyIG5vY2ggZGllIExheW91dCBmdW5rdGlvbiB1bSBkZW0gRGlhZ3JhbW0gZWluZW4gVGl0ZWwgenUgZ2ViZW4gdW5kIHVuc2VyZSBiZWlkZW4gQWNoc2VuYmVzY2hyaWZ0dW5nZW4genUgZXJzdGVsbGVuLg0KDQpgYGB7ciBwbG90KFBsYXRmb3JtUmFua2luZ19HbG9iYWwpLCBlY2hvID0gVFJVRSxtZXNzYWdlPUZBTFNFLHJlc3VsdHM9J21hcmt1cCcsfQ0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgDQogIGdyb3VwX2J5KFBsYXRmb3JtKSAlPiUgDQogIHN1bW1hcml6ZShzdW0oR2xvYmFsX1NhbGVzKSkgICU+JQ0KcmVuYW1lKA0KICAgIEdsb2JhbF9TYWxlcyA9ICJzdW0oR2xvYmFsX1NhbGVzKSINCiAgICApDQpncm91cGVkJEdsb2JhbF9TYWxlczwtYXNfdmVjdG9yKGdyb3VwZWQkR2xvYmFsX1NhbGVzKQ0Kb3JkZXJlZCA8LSBncm91cGVkW29yZGVyKGdyb3VwZWQkR2xvYmFsX1NhbGVzKSwgZGVjcmVhc2luZyA9IEZBTFNFXQ0Kb3JkZXJlZCRQbGF0Zm9ybSA8LSBhc19mYWN0b3Iob3JkZXJlZCRQbGF0Zm9ybSkNCg0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJQbGF0Zm9ybSINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiVmVya2F1ZnN6YWhsZW4gKGluIG1pbykiDQoNCikNCg0KDQpvcmRlcmVkJT4lDQogIHBsb3RfbHkoKSAlPiUgDQogIGFkZF9iYXJzKHg9fmZjdF9yZW9yZGVyKFBsYXRmb3JtLEdsb2JhbF9TYWxlcywgLmRlc2M9InRydWUiKSwNCiAgICAgICAgICAgeT1+R2xvYmFsX1NhbGVzLA0KICAgICAgICAgICBuYW1lPSJWZXJrYXVmc3phaGxlbiBuYWNoIFBsYXRmb3JtIiAsY29sb3JzID0gbXlQYWxldHRlKSAlPiUgDQogIGxheW91dCh0aXRsZT0iVmVya2F1ZnN6YWhsZW4gbmFjaCBQbGF0Zm9ybSIsDQogICAgICAgICB4YXhpcyA9IGF4LA0KICAgICAgICAgeWF4aXMgPSBheQ0KICAgICAgICAgKQ0KYGBgDQpTY2hhdWVuIHdpciB1bnMgZGFzIEVudHN0YW5kZW5lIERpYWdyYW1tIGVpbm1hbCBhdWYgZmFsbGVuIHVucyBkaXJla3QgendlaSBEaW5nZSBhdWYuIFp1bSBlaW5lbiBmZWhsdCBkZXIgTmludGVuZG8gRFMgYXVmIGRlbSBTcGl0emVucGxhdHogenVzYW1tZW4gbWl0IGRlciBQUzIgdW5kIGlzdCBudXIgYXVmIFBsYXR6IDUsIHp1bSBhbmRlcmVuIGlzdCBkZXIgVW50ZXJzY2hpZWQgendpc2NoZW4gZGVuIFNwaXR6ZW5wbMOkdHplbiBiencgZGVtIFNwaXR6ZW5wbGF0eiB1bmQgZGVtIHJlc3QgZGVyIHRvcCA1IGRldXRsaWNoIGdlcmluZ2VyLiBXYXJlbiBlcyBiZWkgZGVyIFNwaWVsZWFuemFobCBub2NoIGZhc3QgNDAlIHVudGVyc2NoaWVkIHp3aXNjaGVuIHBsYXR6IDEvMiB1bmQgcGxhdHogMy00IHNvIHNpbmQgZXMgaGllciBudXIga25hcHAgMjAlLiBEaWUgUmVzdGxpY2hlbiBwbMOkdHplIGRlciBUb3AgNSBzaW5kIGFsbGVyZGluZ3MgZ3LDtsOfdGVudGVpbHMgZ2xlaWNoIGdlYmxpZWJlbi4gWnVzw6R0emxpY2ggenVtIGFic2Fja2VuIGRlcyBOaW50ZW5kbyBEUyB2b24gcGxhdHogMSBhdWYgcGxhdHogNSBoYXQgbnVyIGRpZSBYYm9YMzYwIGlocmUgUG9zaXRpb24gaW4gZGVyIFJhbmdsaXN0ZSB2ZXLDpG5kZXJ0Lg0KDQojIyB7LX0NCg0KIyMjIyMgKkhhYmVuIMOEbHRlcmUgUGxhdGZvcm1lbiBBdXRvbWF0aXNjaCBtZWhyIFNwaWVsZSB1bmQgVmVya8OkdWZlPyogeyNQbGF0Zm9ybVJhbmtpbmdHbG9iYWxfRW5kfQ0KDQpCZWltIEJldHJhY2h0ZW4gYmVpZGVyIERpYWdyYW1tZSBvZGVyIHNvZ2FyIG51ciBlaW5lbSBkZXIgRGlhZ3JhbW1lIGVya2VubnQgZGVyIEF1Zm1lcmtzYW1lIEJldHJhY2h0ZXIgcmVsYXRpdiBzY2huZWxsIGRhcyBoaWVyIGtlaW5lIFBhdXNjaGFsYW50d29ydCBhdWYgZGllc2UgRnJhZ2VzdGVsbHVuZyBtw7ZnbGljaCBpc3QuIERpZXMgaXN0IGFiZXIgaXJnZW5kd2llIHp1IGVyd2FydGVuIGdld2VzZW4gZXMgZ2lidCBzbyB2aWVsZSBGYWt0b3JlbiBkaWUgZGVuIEVyZm9sZyBlaW5lciBiZXN0aW1tdGVuIFBsYXRmb3JtIGJlc3RpbW1lbiB1bmQgZXMgaXN0IHVubcO2Z2xpY2ggZGllc2VzIGFuIGVpbmVtIEZha3RvciBmZXN0enVsZWdlbi4gV3dlbGNoZSBGcmFnZSB3aXIgYWxsZXJkaW5ncyBiZWFudHdvcnRlbiBrb25udGVuLCB6dW1pbmRlc3RlbnMgdGVpbHdlaXNlLCBpc3QgZGllIEZyYWdlIG5hY2ggZGVyICJiZXN0ZW4gUGxhdGZvcm0uIERpZSAqKlBTMioqIGlzdCBzb3dvaGwgd2VpdCBvYmVuIGluIGRlciBTcGllbGVhbnphaGwsIGFscyBhdWNoIFNwaXR6ZW5yZWl0ZXIgaW4gZGVuIEdhbXZlcmvDpHVmZW4uIERlciBOaW50ZW5kbyBEUyBpc3QgendhciBpbiBkZXIgU3BpZWxlYW56YWhsIHNvZ2FyIGtuYXBwIHZvciBkZXIgUFMyIGluIGRlbiB2ZXJrw6R1ZmVuIGFiZXIgd2VpdCBhYmdlc2NobGFnZW4gYXVmIFBsYXR6IDUuIEF1c3NjaGxhZ2dlYmVuZGVyIGFscyB2ZXJnbGVpY2hzYXJndW1lbnQgd8OkcmUgamVkb2NoIGRpZSBBbnphaGwgZGVyIFZlcmthdWZ0ZW4gU3BpZWxlIHBybyBTcGllbCBkb2NoIHdlaXRlcmVzIGhpZXJ6dSBpbSBbQXVzYmxpY2sgaW4gZGllIFp1a3VuZnRdKCNBdXNibGlja0luRGllWnVrdW5mdCkNCg0KT2ZmZW5zaWNodGxpY2ggaXN0IGVpbiBEYXRlbnNhdHogenUgQW56YWhsIGRlciBTcGllbGV2ZXJrw6R1ZmUgdm9yYWxsZW0gZWluIHNvIGzDvGNrZW5oYWZ0ZXIgbmljaHQgb3B0aW1hbCBhYmVyIGRhenUgd2VpdGVyZXMgaW0gW0Zheml0XSgjQXVmZ2V0cmV0ZW5lUHJvYmxlbWUpLg0KDQoqKioNCg0KIyBSZWdpb25hbGUgVW50ZXJzY2hpZWRlIGluIGRlbiBWZXJrYXVmc3phaGxlbiBkZXIgUGxhdGZvcm1lbiB7I1BsYXRmb3JtUmFua2luZ0J5UmVnaW9ufQ0KDQpEYSB3aXIgbnVuIGdla2zDpHJ0IGhhYmVuIHdlbGNoZSBQbGF0Zm9ybWVuIGRpZSBOYXNlIHZvcm5lIGhhYmVuIHfDpHJlIGVzIGRvY2ggSW50ZXJlc3NhbnQgaGVyYXVzenVmaW5kZW4gb2IgZXMgUmVnaW9uYWxlIHVudGVyc2NoaWVkZSBnaWJ0Lg0KKkZhdm9yaXNpZXJlbiB2ZXJzY2hpZWRlbmUgUmVnaW9uZW4gdmVyc2NoaWVkZW5lIFBsYXRmb3JtZW4/IFZlcmthdWZlbiBkaWUgUmVnaW9uZW5oZWltaXNjaGVuIFBsYXRmb3JtZW4gYXV0b21hdGlzY2ggYXVjaCBkaWUgbWVpc3RlbiBTcGllbGU/Kg0KDQpIaWVyYmVpIGvDtm5uZW4gd2lyIG5hdMO8cmxpY2ggbnVyIGRpZSBWZXJrYXVmc3phaGxlbiBoZXJhbnppZWhlbi4gVGhlb3JldGlzY2ggd8OkcmUgYXVjaCBlaW4gVmVyZ2xlaWNoIGluIGFuemFobCBkZXIgU3BpZWxlIG3DtmdsaWNoIHfDvHJkZSBhYmVyIGRpZXNlIEFyYmVpdCBTcHJlbmdlbiBkYSBkZXIgRGF0ZW5zYXR6IGRpZXNlIEluZm9ybWF0aW9uZW4gbmljaHQgb2huZSB3ZWl0ZXJlcyBbaGVyZ2lidF0oI0F1ZmdldHJldGVuZVByb2JsZW1lKS4NClp1bSBCZWFudHdvcnRlbiBkaWVzZXIgRnJhZ2UgYmVudXR6ZW4gd2lyIGVybmV1dCBQYXJldG9kaWFncmFtbWUgdW5kIHVtIHNpY2ggZWluZW4gR3JvYmVuIMO8YmVyYmxpY2sgenUgc2NoYWZmZW4gS3JlaXNkaWFncmFtbWUuIERpZXNlIGhhYmVuIGlocmUgZWlnZW5lbiBbUHJvYmxlbWVdKCNBdWZnZXRyZXRlbmVQcm9ibGVtZSkgYmlldGVuIHVucyBhYmVyIGVpbiBndXRlcyBUb29sIHp1ciBncm9iZW4gw7xiZXJzaWNodCDDvGJlciBkaWUgUHJvemVudHVhbHZlcnRlaWx1bmcgZGVyIEtvbnNvbGVuIHVuZCBicmluZ3QgZXR3YXMgQWJ3ZWNoc2x1bmcgaW4gZGllc2UgYmlzaGVyIHNlaHIgQmFsa2VuZGlhZ3JhbW0gbGFzdGlnZSBhdXNhcmJlaXR1bmcuDQoNCltFaW56dXdlbmRlbiBoaWVyYmVpIGlzdF0oI0F1ZmdldHJldGVuZVByb2JsZW1lKSwgZGFzcyBkaWUgUmVnaW9uZW4gbmF0w7xybGljaCB1bnRlcnNjaGllZGxpY2ggdmllbGUgRWlud29obmVyIGhhYmVuLkVpbiB2ZXJnbGVpY2ggZGVyIGFic29sdXRlbiBTYWxlc3dlcnRlIGlzdCBoaWVyYmVpIG5hdMO8cmxpY2ggbnVyIHdlbmlnIGF1c3NjaGxhZ2dlYmVuZCB6ZWlndCBhYmVyIGVpbmVuIGdlbmVyZWxsZW4gYmVsaWVidGhlaXRzdHJlbmQgZGVyIEtvbnNvbGVuIGluIGRlbiBlaW56ZWxuZW4gUmVnaW9uZW4gYXVmLg0KDQojIyBQbGF0Zm9ybXZlcmdsZWljaCB7LnRhYnNldH0NCg0KIyMjIEJhbGtlbmRpYWdyYW1tZSB7LnRhYnNldH0NCg0KRGllIEVyc3RlbGx1bmcgZGVyIFBhcmV0b2RpYWdyYW1tZSB3ZXJkZSBpY2ggYW4gZGllc2VyIFN0ZWxsZSBuaWNodCBtZWhyIGdlbmF1ZXIgZXJsw6R1dGVybiwgZGEgZGFzIEdydW5kcHJpbnppcCB3ZWl0ZXJoaW4gZGFzIGdsZWljaGUgYmxlaWJ0IGVpbnppZ2VyIHVudGVyc2NoaWVkIHp3aXNjaGVuIGRlbiB2ZXJzY2hpZWRlbmVuIERpYWdyYW1tZW4gaXN0IGhpZXJiZWkgZGVyIHdlcnQgaW4gZGVyIHN1bW1hcml6ZSBGdW5rdGlvbiAqc3VtbWFyaXplKHN1bShFVV9TYWxlcykpKiBFVV9TYWxlcyBmw7xyIEVVIE5BX1NBTEVTIGbDvHIgVVMgdW5kIEpQX1NBTEVTIGbDvHIgSmFwYW4gc293aWUgZGVyIFRpdGVsIHVuZCBkaWUgQWNoc2VuYmVzY2hyaWZ0dW5nZW4uIEVpbmUgZ2VuYXVlcmUgRXJsw6R1dGVydW5nIHp1ciBFcnN0ZWxsdW5nIHZvbiBQYXJldG9kaWFncmFtbWVuIGdpYnQgZXMgW2hpZXJdKCNQbGF0Zm9ybWFuYWx5c2UpLg0KDQojIyMjIEV1cm9wYQ0KYGBge3IgcGxvdChQbGF0Zm9ybVJhbmtpbmdfRVUxKSwgZWNobyA9IFRSVUUsbWVzc2FnZT1GQUxTRSxyZXN1bHRzPSdtYXJrdXAnLH0NCmdyb3VwZWQgPC0gdmdzYWxlcyAgJT4lIA0KICBncm91cF9ieShQbGF0Zm9ybSkgJT4lIA0KICBzdW1tYXJpemUoc3VtKEVVX1NhbGVzKSkgICU+JQ0KcmVuYW1lKA0KICAgIEdsb2JhbF9TYWxlcyA9ICJzdW0oRVVfU2FsZXMpIg0KICAgICkNCmdyb3VwZWQkR2xvYmFsX1NhbGVzPC1hc192ZWN0b3IoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpDQpvcmRlcmVkIDwtIGdyb3VwZWRbb3JkZXIoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpLCBkZWNyZWFzaW5nID0gRkFMU0VdDQpvcmRlcmVkJFBsYXRmb3JtIDwtIGFzX2ZhY3RvcihvcmRlcmVkJFBsYXRmb3JtKQ0KDQoNCmF4IDwtIGxpc3QoDQogIHRpdGxlID0gIlBsYXRmb3JtIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJFVSB2ZXJrw6R1ZmUgKGluIG1pbykiDQoNCikNCg0KDQpvcmRlcmVkJT4lDQogIHBsb3RfbHkoKSAlPiUgDQogIGFkZF9iYXJzKHg9fmZjdF9yZW9yZGVyKFBsYXRmb3JtLEdsb2JhbF9TYWxlcywgLmRlc2M9InRydWUiKSwNCiAgICAgICAgICAgeT1+R2xvYmFsX1NhbGVzLA0KICAgICAgICAgICBuYW1lPSJFVSBWZXJrYXVmc3phaGxlbiBwcm8gUGxhdGZvcm0iICxjb2xvcnMgPSBteVBhbGV0dGUpICU+JSANCiAgbGF5b3V0KHRpdGxlPSJFVSBWZXJrYXVmc3phaGxlbiBwcm8gUGxhdGZvcm0iLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgICkNCmBgYA0KSGF0dGUgaW0gR2xvYmFsZW4gZHVyY2hzY2huaXR0IGRpZSBQUzIgbm9jaCBkZXV0bGljaCBkaWUgTmFzZSB2b3JuZSBpc3QgaW4gRVUgZGllIFBTMyAoMzQzLjcxKSBub2NoIHZvciBkZXIgUFMyICgzMzkuMjkpIHVuZCBkaWVzZSBoYWJlbiBiZWlkZSBub2NoIGVpbmVuIFJlY2h0IHdlaXRlbiBWb3JzcHJ1bmcgYXVmIFBsYXR6IDMgKDI4MC41OCkgdW5kIDQgKDI2OC4zOCkgd2VsY2hlIHJlc3Bla3RpdmUgdm9uIGRlciBYYm94MzYwIHVuZCBkZXIgV2lpIGJlbGVndCB3ZXJkZW4uIERpZSBQbGF5c3RhdGlvbiAxICgyMTMuNikgc2ljaGVydCBzaWNoIGluIEV1cm9wYSBlaW5lbiBwbGF0eiBpbiBkZW4gdG9wIDUgdW5kIGF1Y2ggZGllIFBTNCAoMTIzLjcpIHLDvGNrdCBlaW5lbiBQbGF0eiBuYWNoIFZvcm5lLiBEZW4gd29obCBncsO2w590ZW4gU3BydW5nIGxlZ3QgYWxsZXJkaW5ncyBkZXIgUEMgKDEzOS42OCkgaGluLiBJc3QgZGllc2VyIEdsb2JhbCBub2NoIGF1ZiBQbGF0eiAxMCBzbyBiZWxlZ3QgZXIgaW4gRXVyb3BhIHBsYXR6IDcuIEF1Y2ggYXXDn2VyaGFsYiBkZXIgVG9wIDEwIGdpYnQgZXMgZWluaWdlIHZlcnNjaGllYnVuZ2VuIGF1ZmdydW5kIGRlcyBlaGVyIEdlcmluZ2VyZW4gTWFya2V0c2hhcmVzIHNlaGVuIHdpciBoaWVyIGFsbGVyZGluZ3Mgdm9uIGVpbmVyIGdlbmF1ZXJlbiBBbmFseXNlIGFiLiBadXNhbW1lbmZhc3NlbmQga8O2bm5lbiB3aXIgYWxzbyBzYWdlbiBkYXMgRXVyb3BhIFNvbnkga29uc29sZW4gc293aWUgZGVuIFBjIMO8YmVyZHVyY2hzY2huaXR0bGljaCBnZXJuZSBOdXR6ZW4uDQoNCiMjIyMgTm9yZC1BbWVyaWthDQpgYGB7ciBwbG90KFBsYXRmb3JtUmFua2luZ19OQTEpLCBlY2hvID0gVFJVRSxtZXNzYWdlPUZBTFNFLHJlc3VsdHM9J21hcmt1cCcsfQ0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgDQogIGdyb3VwX2J5KFBsYXRmb3JtKSAlPiUgDQogIHN1bW1hcml6ZShzdW0oTkFfU2FsZXMpKSAgJT4lDQpyZW5hbWUoDQogICAgR2xvYmFsX1NhbGVzID0gInN1bShOQV9TYWxlcykiDQogICAgKQ0KZ3JvdXBlZCRHbG9iYWxfU2FsZXM8LWFzX3ZlY3Rvcihncm91cGVkJEdsb2JhbF9TYWxlcykNCm9yZGVyZWQgPC0gZ3JvdXBlZFtvcmRlcihncm91cGVkJEdsb2JhbF9TYWxlcyksIGRlY3JlYXNpbmcgPSBGQUxTRV0NCm9yZGVyZWQkUGxhdGZvcm0gPC0gYXNfZmFjdG9yKG9yZGVyZWQkUGxhdGZvcm0pDQoNCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiUGxhdGZvcm0iDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIk5BIHZlcmvDpHVmZSAoaW4gbWlvKSINCg0KKQ0KDQoNCm9yZGVyZWQlPiUNCiAgcGxvdF9seSgpICU+JSANCiAgYWRkX2JhcnMoeD1+ZmN0X3Jlb3JkZXIoUGxhdGZvcm0sR2xvYmFsX1NhbGVzLCAuZGVzYz0idHJ1ZSIpLA0KICAgICAgICAgICB5PX5HbG9iYWxfU2FsZXMsDQogICAgICAgICAgIG5hbWU9Ik5BIFZlcmthdWZzemFobGVuIHBybyBQbGF0Zm9ybSIgLGNvbG9ycyA9IG15UGFsZXR0ZSkgJT4lIA0KICBsYXlvdXQodGl0bGU9Ik5BIFZlcmthdWZzemFobGVuIHBybyBQbGF0Zm9ybSIsDQogICAgICAgICB4YXhpcyA9IGF4LA0KICAgICAgICAgeWF4aXMgPSBheQ0KICAgICAgICAgKQ0KYGBgDQpJbSBkaXJla3RlbiBWZXJnbGVpY2ggbWl0IEVVIGbDpGxsdCBoaWVyIHNvZm9ydCBpbnMgQXVnZSwgZGFzcyBkaWUgUGxheXN0YXRpb24gMiAoNTgzLjg0KSB6d2FyIHdlaXRlcmhpbiB2b24gZGVtIGVyc3RlbiBQbGF0eiB2ZXJkcsOkbmd0IHd1cmRlLCBNaWNyb3NvZnRzIFhib3gzNjAgKDYwMS4wNSkgaGllciBTb255cyBQbGF5c3RhdGlvbiAzICgzOTIuMjYpIGFsbGVyZGluZ3MgYXVmIGRlbSBlcnN0ZW4gUGxhdHogYWJsw7ZzdC4gQXVjaCBkaWUgV2lpICg1MDcuNzEpIGhhdCBlcmtlbm5iYXIgbWVociBWZXJrw6R1ZmUgYWxzIG5vY2ggaW4gRXVyb3BhLiBQUzQgKDk2LjgpIHVuZCBQQyAoOTMuMjgpIHNwaWVsZSB2ZXJrYXVmZW4gc2ljaCBpbiBOb3JkLUFtZXJpa2EgZGV1dGxpY2ggd2VuaWdlciBhbHMgaW4gRXVyb3BhIHdvaGluZ2VnZW4gZGllIFJlc3RsaWNoZW4gUGxhdGZvcm1lbiBncsO2w590ZW50ZWlscyDDhGhubGljaCB2ZXJ0ZWlsdCBibGVpYmVuLg0KDQojIyMjIEphcGFuDQpgYGB7ciBwbG90KFBsYXRmb3JtUmFua2luZ19KUDEpLCBlY2hvID0gVFJVRSxtZXNzYWdlPUZBTFNFLHJlc3VsdHM9J21hcmt1cCcsfQ0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgDQogIGdyb3VwX2J5KFBsYXRmb3JtKSAlPiUgDQogIHN1bW1hcml6ZShzdW0oSlBfU2FsZXMpKSAgJT4lDQpyZW5hbWUoDQogICAgR2xvYmFsX1NhbGVzID0gInN1bShKUF9TYWxlcykiDQogICAgKQ0KZ3JvdXBlZCRHbG9iYWxfU2FsZXM8LWFzX3ZlY3Rvcihncm91cGVkJEdsb2JhbF9TYWxlcykNCm9yZGVyZWQgPC0gZ3JvdXBlZFtvcmRlcihncm91cGVkJEdsb2JhbF9TYWxlcyksIGRlY3JlYXNpbmcgPSBGQUxTRV0NCm9yZGVyZWQkUGxhdGZvcm0gPC0gYXNfZmFjdG9yKG9yZGVyZWQkUGxhdGZvcm0pDQoNCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiUGxhdGZvcm0iDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIkpQIHZlcmvDpHVmZSAoaW4gbWlvKSINCg0KKQ0KDQoNCm9yZGVyZWQlPiUNCiAgcGxvdF9seSgpICU+JSANCiAgYWRkX2JhcnMoeD1+ZmN0X3Jlb3JkZXIoUGxhdGZvcm0sR2xvYmFsX1NhbGVzLCAuZGVzYz0idHJ1ZSIpLA0KICAgICAgICAgICB5PX5HbG9iYWxfU2FsZXMsDQogICAgICAgICAgIG5hbWU9IkpQIFZlcmthdWZzemFobGVuIHBybyBQbGF0Zm9ybSIgLGNvbG9ycyA9IG15UGFsZXR0ZSkgJT4lIA0KICBsYXlvdXQodGl0bGU9IkpQIFZlcmthdWZzemFobGVuIHBybyBQbGF0Zm9ybSIsDQogICAgICAgICB4YXhpcyA9IGF4LA0KICAgICAgICAgeWF4aXMgPSBheQ0KICAgICAgICAgKQ0KYGBgDQpKYXBhbiBpc3Qgd29obCBkZXIgZ3LDtsOfdGUgQXVzcmVpw59lciBkZXIgZHJlaSBSZWdpb25lbi4gSGllciBmw7xocnQgZGVyIE5pbnRlbmRvIERTICgxNzUuNTcpIGRpZSBMaXN0ZSBhbi4gQXVjaCBkZXIgQWJzdGFuZCBhdWYgUGxhdHogMiBpc3QgaGllciBncsO2w59lciBhbHMgaW4gZGVuIGFuZGVyZW4gUmVnaW9uZW4gd2VsY2hlciBuaWNodCB2b24gZGVyIFBsYXlzdGF0aW9uIDIgKFBsYXR6IDMpIHNvbmRlcm4gZGVyIFBsYXlzdGF0aW9uIDEgYmVsZWd0IHdpcmQuIFdlaXQgYWJnZXNjaGxhZ2VuIGlzdCBkaWUgUFMyICgxMzkuMiBtaW8pIHZvbiBkZXIgUFMxKDEzOS44MikgamVkb2NoIG5pY2h0LiBTb255cyBiZWlkZSBLb25zb2xlbiBzaW5kIGF1Y2ggZGllIGVpbnppZ2VuIG5pY2h0IE5pbnRlbmRvIGtvbnNvbGVuIGluIGRlbiBUb3AgNy4gQWxsZWdlbWVpbiBpc3QgaGllciBlaW4gZ3Jvw59lciBGb2t1cyBhdWYgSmFwYW5pc2NoZSB1bnRlcm5laG1lbiB6dSBlcmtlbm5lbiB3ZW5uIG1hbiBiZWRlbmt0IGRhcyBkaWUgZXJzdGUsIG5pY2h0IGphcGFuaXNjaGUga29uc29sZSwgZGllIFhib3ggMzYwICgxMi40MykgYXVmIFBsYXR6IDE3IGlzdC4gSmFwYW5pc2NoZSBoZXJzdGVsbGVyIHNpbmQgaW4gZGVyIFNwaWVsZWluZHVzdHJpZSB3ZWl0IHZlcmJyZWl0ZXQgZWluIHNvIGV4dHJlbWVzIFZlcmjDpGx0bmlzIGlzdCBHbG9iYWwgamVkb2NoIG5pY2h0IGRpZSBOb3JtLiBTY2hhdWVuIHdpciB1bnMgZGFzIGdhbnplIGVpbm1hbCBnZW5hdWVyIGFscyBLcmVpc2RpYWdyYW1tZSBhbiB1bSBkaWUgVmVyaMOkbHRuaXNlIGV0d2FzIGRldXRsaWNoZXIgenUgbWFjaGVuLg0KDQojIyMgS3JlaXNkaWFncmFtbWUgey50YWJzZXR9DQoNCkRhIHdpciBiaXNoZXIgbm9jaCBrZWluZSBLcmVpc2RpYWdyYW1tZSBnZW51dHp0IGhhYmVuIHNjaGF1ZW4gd2lyIHVucyBlcnN0IG1hbCBkaWUgVW50ZXJzY2hpZWRlIGluIGRlciBEaWFncmFtbWVyc3RlbGx1bmcgYW4gYmV2b3Igd2lyIHVucyBhdWYgZGllIEFuYWx5c2UgZWJlbmplbmVyIERpYWdyYW1tZSBzdMO8cnplbi4gRGVyIGVpbmZhY2hoZWl0IGhhbGJlciBzY2hhdWVuIHdpciB1bnMgZGFzIGdhbnplIG51ciBhbSBCZWlzcGllbCBFdXJvcGEgYW4sIGRpZSBhbmRlcmVuIERpYWdyYW1tZSB1bnRlcnNjaGVpZGVuIHNpY2ggYWJlciBudXIgaW4gZGVtIFdlcnQgaW4gZGVyICpzdW1tYXJpemUqIGZ1bmt0aW9uIHNvd2llIGRlbiBBY2hzZW4tIHVuZCBkZXIgRGlhZ3JiZXNjaHJpZnR1bmcuIERlciBHcnVuZGF1ZmJhdSBkZXIgRGlhZ3JhbW0gZXJzdGVsbHVuZyBpc3QgaGllciB3aWVkZXIgw6RobmxpY2ggd2llIGJlaSBkZW4gUGFyZXRvZGlhZ3JhbW1lbi4gWnVlcnN0IGdydXBwaWVyZW4gd2lyIGRpZSBEYXRlbiwgc29ydGllcmVuIHNpZSBuYWNoIEFuemFobCBkZXIgVmVya8OkdWZlIHVuZCBlcnN0ZWxsZW4gdW5zZXJlIEFjaHNlbmJlc2NocmlmdHVuZ2VuLiBEYW5hY2ggenVtIGludGVyZXNzYW50ZW4gVGVpbCBkZXIgRGlhZ3JhbW1lcnN0ZWxsdW5nIHdlbGNoZXIgc2ljaCBlaWdlbnRsaWNoIGF1Y2ggbmljaHQgZ3Jvw58gdm9uIGRlbiBQYXJldG9kaWFncmFtbWVuIHVudGVyc2NoZWlkZXQuIFdpciDDvGJlcmdlYmVuIHVuc2VyZSBTb3J0aWVydGVuIERhdGVuIGFuICpQbG90X2x5KCkqIHVuZCB2ZXJ3ZW5kZW4gZGllIEZ1bmt0aW9uICphZGRfcGllKiBtaXQgZW50c3ByZWNoZW5kZW4gUGFyYW1ldGVybiB6dXIgRGlhZ3JhbW0gZXJzdGVsbHVuZy4gRGllc2UgdW50ZXJzY2hlaWRlbiBzaWNoIGV0d2FzIHZvbiBkZW4gUGFyZXRvZGlhZ3JhbW1lbi4gKlZhbHVlcyogc2luZCBoaWVyYmVpIGRpZSBXZXJ0ZSwgZGllIGRpZSBHcsO2w59lIHVuZCAqbGFiZWxzKiBkaWUgQmV6ZWljaG51bmcgZGVyICJLdWNoZW5zdMO8Y2tlIiBmZXN0bGVnZW4uIERlciBsZXR6dGUgaW50ZXJlc3NhbnRlIFBhcmFtZXRlciBpc3QgKnRleHRpbmZvKiBtaXQgd2VsY2hlbSBGZXN0Z2VsZWd0IHdpcmQgd2FzIGFscyB0ZXh0IGluIGRlbiBBYnNjaG5pdHRlbiBhdWZnZWbDvGhydCB3aXJkLiBJbiB1bnNlcmVtIEJlaXNwaWVsIG51dHplbiB3aXIgaGllciAqdGV4dGluZm89J2xhYmVsK3BlcmNlbnQnKiB1bWQgc293b2hsIGRpZSBCZXplaWNobnVuZ2VuIGFscyBhdWNoIGRlbiBHZW5hdWVuIFByb3plbnR3ZXJ0IGFuenV6ZWlnZW4uDQoNCiMjIyMgRXVyb3BhDQoNCmBgYHtyIHBsb3QoUGxhdGZvcm1SYW5raW5nX0VVMiksIGVjaG8gPSBUUlVFLG1lc3NhZ2U9RkFMU0UscmVzdWx0cz0nbWFya3VwJyx9DQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoUGxhdGZvcm0pICU+JSANCiAgc3VtbWFyaXplKHN1bShFVV9TYWxlcykpICAlPiUNCnJlbmFtZSgNCiAgICBHbG9iYWxfU2FsZXMgPSAic3VtKEVVX1NhbGVzKSINCiAgICApDQpncm91cGVkJEdsb2JhbF9TYWxlczwtYXNfdmVjdG9yKGdyb3VwZWQkR2xvYmFsX1NhbGVzKQ0Kb3JkZXJlZCA8LSBncm91cGVkW29yZGVyKGdyb3VwZWQkR2xvYmFsX1NhbGVzKSwgZGVjcmVhc2luZyA9IEZBTFNFXQ0Kb3JkZXJlZCRQbGF0Zm9ybSA8LSBhc19mYWN0b3Iob3JkZXJlZCRQbGF0Zm9ybSkNCg0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJQbGF0Zm9ybSINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiRVUgdmVya8OkdWZlIChpbiBtaW8pIg0KDQopDQoNCm9yZGVyZWQlPiUNCiAgcGxvdF9seSgpICU+JSANCiAgYWRkX3BpZSh2YWx1ZXMgPX5HbG9iYWxfU2FsZXMsbGFiZWxzPX5QbGF0Zm9ybSx0ZXh0aW5mbz0nbGFiZWwrcGVyY2VudCcsICB0ZXh0cG9zaXRpb24gPSAnaW5zaWRlJywNCiAgICAgICAgICAgbmFtZT0iRVUgVmVya2F1ZnN6YWhsZW4gcHJvIFBsYXRmb3JtIiAsY29sb3JzID0gbXlQYWxldHRlKSAlPiUgDQogIGxheW91dCh0aXRsZT0iRVUgVmVya2F1ZnN6YWhsZW4gcHJvIFBsYXRmb3JtIiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5LA0KICAgICAgICAgc2hvd2xlZ2VuZCA9IEZBTFNFLA0KICAgICAgICAgYXV0b3NpemUgPSBGDQogICAgICAgICApDQpgYGANCk9obmUgZGlyZWt0ZSBHbG9iYWxlIHZlcmdsZWljaHNkaWFncmFtbWUga8O2bm5lbiB3aXIgaGllciBpbSBlcnN0ZW4gU2Nocml0dCBub2NoIGtlaW5lIGdyb8OfYXJ0aWdlbiBBdXNzYWdlbiB0cmVmZmVuIHdlcmRlbiBhYmVyIGltIHNww6R0ZXJlbiBWZXJsYXVmIGF1ZiBkaWVzZSBlaW5nZWhlbi4gV2FzIHdpciBoaWVyIGFsbGVyZGluZ3MgZ3V0IGVya2VubmVuIEvDtm5uZW4gaXN0LCBkYXNzIGRpZSBncsO2w590ZW4gdmllciBQbGF0Zm9ybWVuIGhpZXIgNTAuNSUgZGVyIEdlc2FtdHZlcmvDpHVmZSBhdXNtYWNoZW4gdW5kIFNvbnlzIEtvbnNvbGVuIHNvZ2FyIDI4JS4NCg0KIyMjIyBOb3JkLUFtZXJpa2ENCmBgYHtyIHBsb3QoUGxhdGZvcm1SYW5raW5nX05BMiksIGVjaG8gPSBUUlVFLG1lc3NhZ2U9RkFMU0UscmVzdWx0cz0nbWFya3VwJyx9DQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoUGxhdGZvcm0pICU+JSANCiAgc3VtbWFyaXplKHN1bShOQV9TYWxlcykpICAlPiUNCnJlbmFtZSgNCiAgICBHbG9iYWxfU2FsZXMgPSAic3VtKE5BX1NhbGVzKSINCiAgICApDQpncm91cGVkJEdsb2JhbF9TYWxlczwtYXNfdmVjdG9yKGdyb3VwZWQkR2xvYmFsX1NhbGVzKQ0Kb3JkZXJlZCA8LSBncm91cGVkW29yZGVyKGdyb3VwZWQkR2xvYmFsX1NhbGVzKSwgZGVjcmVhc2luZyA9IEZBTFNFXQ0Kb3JkZXJlZCRQbGF0Zm9ybSA8LSBhc19mYWN0b3Iob3JkZXJlZCRQbGF0Zm9ybSkNCg0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJQbGF0Zm9ybSINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiTkEgdmVya8OkdWZlIChpbiBtaW8pIg0KDQopDQoNCg0Kb3JkZXJlZCU+JQ0KICBwbG90X2x5KCkgJT4lIA0KICBhZGRfcGllKHZhbHVlcyA9fkdsb2JhbF9TYWxlcyxsYWJlbHM9flBsYXRmb3JtLHRleHRpbmZvPSdsYWJlbCtwZXJjZW50JywgdGV4dHBvc2l0aW9uID0gJ2luc2lkZScsDQogICAgICAgICAgIG5hbWU9Ik5BIFZlcmthdWZzemFobGVuIHBybyBQbGF0Zm9ybSIgLGNvbG9ycyA9IG15UGFsZXR0ZSkgJT4lIA0KICBsYXlvdXQodGl0bGU9Ik5BIFZlcmthdWZzemFobGVuIHBybyBQbGF0Zm9ybSIsDQogICAgICAgICB4YXhpcyA9IGF4LA0KICAgICAgICAgeWF4aXMgPSBheSwNCiAgICAgICAgIHNob3dsZWdlbmQgPSBGQUxTRSwNCiAgICAgICAgIGF1dG9zaXplID0gRg0KICAgICAgICAgKQ0KYGBgDQpCZWltIGJldHJhY2h0ZW4gZGVzIERpYWdyYW1tZXMgZsO8ciBBbWVyaWthIHNlaGVuIHdpciBkYXMgZGllIFRvcCA0LCB3ZWxjaGUgd2VpdGVyaGluIGF1cyBYYm9YMzYwIFdpaSBQczIgdW5kIFBTMyBiZXN0ZWhlbiwgbnVyIG5vY2ggNDcuNTMlIGF1c21hY2hlbi4gR3LDtsOfdGVyIFZlcmxpZXJlciBzaW5kIGhpZXIgU29ueXMgS29uc29sZW4sIHdlbGNoZSBudXIgbm9jaCAyMi4yMyUgYXVzbWFjaGVuLg0KDQojIyMjIEphcGFuDQoNCmBgYHtyIHBsb3QoUGxhdGZvcm1SYW5raW5nX0pQMiksIGVjaG8gPSBUUlVFLG1lc3NhZ2U9RkFMU0UscmVzdWx0cz0nbWFya3VwJyx9DQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoUGxhdGZvcm0pICU+JSANCiAgc3VtbWFyaXplKHN1bShKUF9TYWxlcykpICAlPiUNCnJlbmFtZSgNCiAgICBHbG9iYWxfU2FsZXMgPSAic3VtKEpQX1NhbGVzKSINCiAgICApDQpncm91cGVkJEdsb2JhbF9TYWxlczwtYXNfdmVjdG9yKGdyb3VwZWQkR2xvYmFsX1NhbGVzKQ0Kb3JkZXJlZCA8LSBncm91cGVkW29yZGVyKGdyb3VwZWQkR2xvYmFsX1NhbGVzKSwgZGVjcmVhc2luZyA9IEZBTFNFXQ0Kb3JkZXJlZCRQbGF0Zm9ybSA8LSBhc19mYWN0b3Iob3JkZXJlZCRQbGF0Zm9ybSkNCg0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJQbGF0Zm9ybSINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiSlAgdmVya8OkdWZlIChpbiBtaW8pIg0KDQopDQoNCg0Kb3JkZXJlZCU+JQ0KICBwbG90X2x5KCkgJT4lIA0KICBhZGRfcGllKHZhbHVlcyA9fkdsb2JhbF9TYWxlcyxsYWJlbHM9flBsYXRmb3JtLHRleHRpbmZvPSdsYWJlbCtwZXJjZW50JywgdGV4dHBvc2l0aW9uID0gJ2luc2lkZScsDQogICAgICAgICAgIG5hbWU9IkpQIFZlcmthdWZzemFobGVuIHBybyBQbGF0Zm9ybSIgLCAgcm90YXRpb24gPSA0MCwgY29sb3JzID0gbXlQYWxldHRlKSAlPiUgDQogIGxheW91dCh0aXRsZT0iSlAgVmVya2F1ZnN6YWhsZW4gcHJvIFBsYXRmb3JtIiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5LA0KICAgICAgICAgc2hvd2xlZ2VuZCA9IEZBTFNFLA0KICAgICAgICAgYXV0b3NpemUgPSBGDQogICAgICAgICANCiAgICAgICAgICkNCmBgYA0KSW4gSmFwYW4gbWFjaGVuIGRpZSBUb3AgNCA0NC4yMyUgYXVzIGJlc3RlaGVuIGFiZXIgYmlzIGF1ZiBkaWUgUFMyIGF1cyBnw6RuemxpY2ggYW5kZXJlbiBLb25zb2xlbi4gRGEgU29ueXMgUFMzIHZvbiBkZXIgUFMgZXJzZXR6dCB3aXJkIGhhbHRlbiBkaWVzZSB3ZWl0ZXJoaW4gMjEuNiUgZGVyIFRvcCA0LiBOaW50ZW5kbyBob2x0IHNpY2ggaGllciBqZWRvY2ggZGVuIEdyw7bDn3RlbiBBbnRlaWwgbWl0IDIyLjYzJS4gRWluIHZlcmdsZWljaCBkaWVzZXIgV2VydGUgaXN0IGplZG9jaCwgd2llIGJlcmVpdHMgaW0gVm9yc3Bhbm4gZGVyIFBsYXRmb3JtIFJhbmtpbmdzIGVyd8OkaG50IG1pdCBQcm9ibGVtZW4gZ2VoYWZ0LiBHZW5hdWVyZXMgaGllcnp1IHdpZSBiZXJlaXRzIGVyd8OkaG50IGltIFtGYXppdF0oI0F1ZmdldHJldGVuZVByb2JsZW1lKS4NCg0KIyMgey19DQoNCg0KKioqDQoNCiMgUGxhdGZvcm0gVmVya2F1ZnN6YWhsZW4gaW0gbGF1ZmUgZGVyIEphaHJlIHsjU2FsZXNQZXJQbGF0Zm9ybX0NCg0KTmFjaGRlbSB3aXIgdW5zIGRpZSBQbGF0Zm9ybSB2ZXJ0ZWlsdW5nIGFuZ2VzY2hhdXQgaGFiZW4gc3RlbGx0IHNpY2ggZGllIEZyYWdlIG9iIGVzIGltIGxhdWZlIGRlciBKYWhyZSB1bnRlcnNjaGllZGUgaW4gZGVuIFZlcmvDpHVmZW4gZ2lidC4NCg0KDQpVbSB1bnMgZGllcyBhbnp1c2NoYXVuIHZlcndlbmRlbiB3aXIgZWluZSBuZXVlIGFydCBkZXIgR3JhZmlrIGRpZSB3aXIgYmlzaGVyIG5vY2ggbmljaHQgdmVyd2VuZGV0IGhhYmVuLiBadW0gZXJzdGVsbGVuIGRlciBHcmFmaWsgZ3J1cHBpZXJlbiB3aXIgenVlcnN0IHdpZWRlciB1bnNlcmUgRGF0ZW4gdW5kIGFkZGllcmVuIGRpZSB3ZXJ0ZSBkZXIgU2FsZXMgcHJvIEphaHIgdW5kIFBsYXRmb3JtIGF1Zi4gWlVzw6R0emxpY2ggenVtIEZpbHRlciBkZXIgdW5nw7xsdGlnZW4gSmFocmUgZmlsdGVyIHdpciBhbGxlcmRpbmdzIGFsbGUgU3VtbWVuIG1pdCB3ZW5pZ2VyIGFscyA2MCBtaW8gaW4gU2FsZXMuIERpZXMgaXN0IHVtIGVpbmUgw5xiZXJsYWR1bmcgZGVzIERpYWdyYW1tcyB6dSB2ZXJoaW5kZXJuIGbDvGhydCBhYmVyIHp1IGFuZGVyZW4gW1Byb2JsZW1lbl0oI0F1ZmdldHJldGVuZVByb2JsZW1lKS4gTmV1IGluIGRlciBlcnN0ZWxsdW5nIGRpZXNlcyBEaWFncmFtbXMgc2luZCBhdWNoIGRpZSBiZWZlaGxlICphcnJhbmdlKCkqIHVuZCAqc2xpY2UoKSouIEFycmFuZ2Ugc29ydGllcnQgZGllIFRhYmVsbGUgYW5oYW5kIGRlciBnZWdlYmVuZW4gU3BhbHRlIGluIHVuc2VyZW0gZmFsbCBpc3QgZGFzIGRpZSBTdW1tZSBkZXIgR2xvYmFsZW4gdmVya8OkdWZlLiBTbGljZSBlbnRmZXJudCBhbGxlIFNwYWx0ZW4gYmlzIGF1ZiBqZW5lLCB3ZWxjaGUgd2lyIHZlcndlbmRlbiB3b2xsZW4uIE5ldSBiZWkgZGVyIERpYWdhbW0gZXJzdGVsbHVuZyBzaW5kIGhpZXIgZGllIFBhcmFtZXRlciAqbW9kZSA9ICdub25lJyogc293aWUgKnN0YWNrZ3JvdXAgPSAnb25lJyogd2VsY2hlIGRpZSBoaWVyIHp1IHNlaGVuZGUgR3JhZmlrIGVyemV1Z2VuLg0KYGBge3IgcGxvdChTYWxlc1BlclBsYXRmb3JtYnlZZWFyKSwgZWNobyA9IFRSVUUsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J21hcmt1cCcsIH0NCg0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgZ3JvdXBfYnkoWWVhciwgUGxhdGZvcm0pICU+JQ0KICBkcGx5cjo6c3VtbWFyaXplKGdyX3N1bSA9IHN1bShHbG9iYWxfU2FsZXMpKSAlPiUgZmlsdGVyKFllYXIhPSdOL0EnKSU+JWZpbHRlcihZZWFyIT0yMDIwKSAlPiUgZmlsdGVyKFllYXIhPScyMDE3JykgICU+JSBmaWx0ZXIoZ3Jfc3VtPjYwKSU+JQ0KICBhcy5kYXRhLmZyYW1lKCkNCmdyb3VwZWQgPC0gZ3JvdXBlZCAlPiVhcnJhbmdlKGRlc2MoZ3Jfc3VtKSkgJT4lIA0KICBncm91cF9ieShZZWFyLCBQbGF0Zm9ybSkgJT4lDQogIHNsaWNlKDE6MykNCg0KZmlsdGVyZWQgPC0gZ3JvdXBlZCAlPiUgc2VsZWN0KFllYXIsUGxhdGZvcm0sZ3Jfc3VtKQ0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiSmFociINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAidmVya8OkdWZlIHBybyBQbGF0Zm9ybSAoaW4gbWlvKSINCg0KKQ0KDQoNCmZpbHRlcmVkICU+JQ0KcGxvdF9seSh4ID0gflllYXIsIHkgPSB+Z3Jfc3VtLCB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ25vbmUnLCBzdGFja2dyb3VwID0gJ29uZScsY29sb3IgPSB+UGxhdGZvcm0gLGNvbG9ycyA9IG15UGFsZXR0ZSklPiUgDQogIGxheW91dCh0aXRsZT0iVmVya8OkdWZlIHBybyBQbGF0Zm9ybSB2b24gMTk4MC0yMDE2IiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5DQogICAgICAgICApDQoNCmBgYA0KSW0gZXJzdGVuIE1vbWVudCBpc3QgZGllIEdyYWZpayBzZWhyIHZlcndpcnJlbmQgYWJlciBkcsO2c2VsbiB3aXIgZGFzIGdhbnplIGVpbm1hbCBnZW5hdWVyIGF1Zi4gWnVlcnN0IGVpbm1hbCBmw6RsbHQgYXVmLCBkYXNzIGRpZSBKYWhyZSAxOTgwLTE5ODggc293aWUgMTk5MC0xMDA1IHVuZCAyMDE2IGZlaGxlbi4gRGllcyBsaWVndCBhbiBkZW4gb2JlbiBnZXfDpGhsdGVuIEZpbHRlcm4gdW5kIGRlbiBpbiBkZW4gSmFocmVuIHBybyBQbGF0dGZvcm0gZ2VtZXNzZW4genUgZ2VyaW5nZW4gVmVya2F1ZnN6YWhsZW4uIFp3aXNjaGVuIGRlbiBKYWhyZW4gMTk5NiB1bmQgMjAwMCBpc3QgaGllciBudXIgZGllIFBsYXlzdGF0aW9uLCB3ZWxjaGUgMTk5NCB2ZXLDtmZmZW50bGljaHQgd3VyZGUgenUgZXJrZW5uZW4uIEltIEphaHJlIDIwMDAgd2lyZCBkaWVzZSBkYW5uIHZvbiBkZXIgUGxheXN0YXRpb24gMiwgd2VsY2hlIGFtIDA0LjAzLjIwMDAgcmVsZWFzdCB3dXJkZSBhYmdlbMO2c3QuIEF1Y2ggZGVyIEdhbWVib3kgQWR2YW5jZWQgaGllciBpbiBkZW4gSmFocmVuIDIwMDAtMjAwMyBzb3dpZSAyMDA0IHp1IGVya2VubmVuLCBvYndvaGwgZGllc2VyIEdsb2JhbCBlcnN0IE1pdHRlIGRlcyBKYWhyZXMgMjAwMSByZWxlYXN0IHd1cmRlLjIwMDQgd2lyZCBkaWUgUGxheXN0YXRpb24gMiBkYW5uIHZvbiBkZXIgWGJveCwgd2VsY2hlIGFtIDIyLjAyLjIwMDIgZXJzdG1hbHMgdmVyw7ZmZmVudGxpY2ggd3VyZGUsIGt1cnp6ZWl0aWcgYWJnZWzDtnN0IGJldm9yIGRpZSBXaWkoMDIuMTIuMjAwNikgbWl0IG51ciBlaW5lbSBWZXJrYXVmc21vbmF0IGRlcyBKYWhyZXMgMjAwNiBkaWUgRsO8aHJ1bmcgw7xiZXJuaW1tdC4gQXVjaCBkaWUgVmVya2F1ZnN6YWhsZW4gZGVzIE5pbnRlbmRvIERTICgwMi4xMi4yMDA0KSBzaW5kIGluIGRlbiBKYWhyZW4gMjAwNS0yMDEwIGd1dCBlcmtlbm5iYXIuIERpZSBYYm9YMzYwICgxMC4xMi4yMDA1KSDDvGJlcm5pbW10IGFiIDIwMDcgZGVuIGVyc3RlbiBQbGF0eiBkZXIgUmFuZ2xpc3RlIHVuZCB3aXJkIGVyc3QgMjAxNCB2b24gZGVyIFBTNCgxNS4xMS4yMDEzKSBhYmdlbMO2c3QuIA0KDQoNCkFsbGdlbWVpbiBpc3QgaGllciBlaW4gVHJlbmQgZXJrZW5uYmFyLiBNZWlzdCB2ZXJrYXVmZW4gUGxhdGZvcm1lbiB3aWUgenUgZXJ3YXJ0ZW4gZWluaWdlIFplaXQgbmFjaCBSZWxlYXNlIGRpZSBtZWlzdGVuIFNwaWVsZS4gRXJzdGF1bmxpY2hlcndlaXNlIGlzdCBkaWVzIGplZG9jaCBuaWNodCBrdXJ6IG5hY2ggUmVsZWFzZSBzb25kZXJuIHouVC4gZXJzdCBlaW5pZ2UgSmFocmUgc3DDpHRlci4gSW50ZXJlc3NhbnQgd8OkaHJlIGhpZXIgZWluZSBkZXRhaWxsaWVydGVyZSBhbmFseXNlIGFiZXIgd2VpdGVyZXMgZGF6dSBbaGllcl0oI0F1c2JsaWNrSW5EaWVadWt1bmZ0KS4NCg0KDQoNCioqKg0KDQojIFB1Ymxpc2hlciBWZXJnbGVpY2ggeyNQdWJsaXNoZXJSZWxlYXNlc30NCg0KTmFjaGRlbSB3aXIgdW5zIG51biBlaW5lIMOcYmVyc2ljaHQgw7xiZXIgZGllIFBsYXRmb3JtZW4gZ2VtYWNodCBoYWJlbiB3w6RyZSBlcyBkb2NoIGludGVyZXNzYW50IHp1IHdpc3NlbiBvYiBzaWNoIG5lYmVuIGJlc3RpbW10ZW4gUGxhdGZvcm1lbiBhdWNoIGJlc3RpbW10ZSBFbnR3aWNrbGVyL1B1Ymxpc2hlciBow6R1ZmVuLiBBbnp1bmVobWVuIGlzdCBoaWVyYmVpIGRhcyBOYW1lbmhhZnRlIFB1Ymxpc2hlciB3aWUgRUEgdW5kIE5pbnRlbmRvIGRpZSBMaXN0ZSBhbmbDvGhyZW4uIEhpZXJ6dSB2ZXJ3ZW5kZW4gd2lyIHdpZWRlcnVtIFBhcmV0b2RpYWdyYW1tZS4gRWluZSBnZW5hdWVyZSBlcmtsw6RydW5nIHp1ciBlcnN0ZWxsdW5nIGViZW5qZW5lciBnaWJ0IGVzIFtoaWVyXSgjUGxhdGZvcm1hbmFseXNlKS4gRWluemlnZSBuZXVlcnVuZyBpbiBkaWVzZW0gYWJzY2huaXR0IGlzdCBkYXMgS8O8cnplbiBkZXIgTmFtZW4gdW0gZGllIEJlZ3JpZmZlICJFbnRlcnRhaW5tZW50IiwgIkludGVyYWN0aXZlIiwgIkdhbWUiLCAiR2FtZXMiIHVuZCAiU3R1ZGlvcyIgZGEgZGllcyBkaWUgTmFtZW4gbnVyIHVubsO2dGlnIHZlcmzDpG5nZXJ0LiBVbSBkaWVzIHp1IGVycmVpY2hlbiBtdXR6ZW4gd2lyIGRpZSBGdW5rdGlvbiAqc3RyX3JlbW92ZV9hbGwoKSogYXVmIGRpZSBTcGFsdGUgUHVibGlzaGVyLiANCg0KIyMgUHVibGlzaGVyIHsudGFic2V0fQ0KDQojIyMgbmFjaCBBbnphaGwNCmBgYHtyIHBsb3QyLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgDQogIGdyb3VwX2J5KFB1Ymxpc2hlcikgJT4lIA0KICBzdW1tYXJpemUoQW56YWhsID1uKCkpICU+JSAgDQogIGZpbHRlcihBbnphaGw+MTAwKSAlPiUgZmlsdGVyKFB1Ymxpc2hlciE9IlVua25vd24iKQ0KDQoNCg0KDQpQdWJsaXNoZXJTYWxlcyA8LSB2Z3NhbGVzICU+JSANCiAgZ3JvdXBfYnkoUHVibGlzaGVyKSAlPiUgDQogIHN1bW1hcml6ZShzdW0oR2xvYmFsX1NhbGVzKSkgJT4lDQpyZW5hbWUoDQogICAgR2xvYmFsX1NhbGVzID0gInN1bShHbG9iYWxfU2FsZXMpIg0KICAgICkgJT4lIGZpbHRlcihHbG9iYWxfU2FsZXM+MzAwKQ0KDQoNCg0KZ3JvdXBlZCA8LSBncm91cGVkICAlPiUgZmlsdGVyKFB1Ymxpc2hlciAlaW4lIFB1Ymxpc2hlclNhbGVzJFB1Ymxpc2hlcikNCg0KDQpvcmRlcmVkIDwtIGdyb3VwZWRbb3JkZXIoZ3JvdXBlZCRBbnphaGwpLCBkZWNyZWFzaW5nID0gRkFMU0VdDQpvcmRlcmVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKG9yZGVyZWQkUHVibGlzaGVyLCAiRW50ZXJ0YWlubWVudCIpDQpvcmRlcmVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKG9yZGVyZWQkUHVibGlzaGVyLCAiSW50ZXJhY3RpdmUiKQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIlN0dWRpb3MiKQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIkdhbWVzIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwob3JkZXJlZCRQdWJsaXNoZXIsICJHYW1lIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtIGFzX2ZhY3RvcihvcmRlcmVkJFB1Ymxpc2hlcikNCg0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJQdWJsaXNoZXIiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIkFuemFobCINCikNCm9yZGVyZWQlPiUNCiAgcGxvdF9seSgpICU+JSANCiAgYWRkX2JhcnMoeD1+ZmN0X3Jlb3JkZXIoUHVibGlzaGVyLEFuemFobCwgLmRlc2M9InRydWUiKSwNCiAgICAgICAgICAgeT1+QW56YWhsLA0KICAgICAgICAgICBuYW1lPSJTcGllbGUgQW56YWhsIHBybyBQdWJsaXNoZXIiDQogICAgICAgICAgICxjb2xvcnMgPSBteVBhbGV0dGUpICU+JSANCiAgbGF5b3V0KHRpdGxlPSJTcGllbGUgQW56YWhsIHBybyBQdWJsaXNoZXIiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgIA0KICAgICAgICAgKQ0KYGBgDQoNCkJldHJhY2h0ZW4gd2lyIHp1ZXJzdCBlaW5tYWwgZGllIEFuemFobCBkZXIgU3BpZWxlcmVsZWFzZXMuIFdlbmlnIMO8YmVyYXNjaGVuZCBpc3QgaGllciBFQSAoMTM1MSksIG1pdCBqw6RocmxpY2ggdmVyw7ZmZmVudGxpY2hlbmRlbiBuYW1lbmhhZnRlbiBTcGllbGVuIHdpZSBGSUZBIHVuZCBNYWRkZW4gTkZMIHNvd2llIGFuZGVyZW4gYmVrYW5udGVuIFJlaWhlbiB3aWUgTmVlZCBmb3IgU3BlZWQsIEJhdHRsZWZpZWxkIG9kZXIgU2ltcywgYW5mw7xocmVyIGRlciBMaXN0ZS4gQW4gendlaXRlciBzdGVsbGUgYmVmaW5kZXQgc2ljaCBBY3RpdmlzaW9uICg5NzUpIGRpZSB1bnRlciBhbmRlcmVtIFNwaWVsZSB3aWUgV29ybGQgb2YgV2FyY3JhZnQsIGRpZSBEaWFibG8gcmVpaGUgc293aWUgQ2FuZHkgQ3J1c2ggZW50d2lja2VsdGVuLiBadW0gWmVpdHB1bmt0IGRlciBFcnN0ZWxsdW5nIGRpZXNlciBBcmJlaXQgc2luZCBkaWVzZSBub2NoIGVpbiBlaWdlbmVyIEtvbnplcm4gd2VyZGVuIGFsbGVyZGluZ3Mgdm9yYXVzaWNodGxpY2ggMjAyMyBUZWlsIHZvbiBNaWNyb3NvZnQuIERhcmF1ZiBmb2xnZW4gaW4ga3VyemVuIGFic3TDpG5kZW4gVWJpc29mdCAoOTIxKSwgd2VsY2hlIGbDvHIgQXNzYXNpbnMgQ3JlZWQsIFJhaW5ib3ggc2l4IG9kZXIgQW5ubyBiZWthbm50IHNpbmQsIHNvd2llIFRIUSAgbWl0IDcxNSAoR290aGljLCBEYXJrc2lkZXJzLCBUaXRhblF1ZXN0KS4gQXVjaCBOaW50ZW5kbyAoNzAzKSBtaXQgTWFyaW8sIFBva2Vtb24gdW5kIFplbGRhIHNvd2llIFNvbnkgKDYzOCksIGJla2FubnQgZHVyY2ggZGllIEdyYW4gVG91cmlzbW8gdW5kIFVuY2hhcnRlZCBSZWloZSBzb3dpZSBUaGUgbGFzdCBvZiBVcywgc2luZCBuaWNodCB3ZWl0IGFiZ2VzY2hsYWdlbi4gRGVuIGxldHp0ZW4gcGxhdHogZGVyIFRvcCBQdWJsaXNoZXIgYmVsZWd0IFRha2UgVHdvLCB3ZWxjaGUgZsO8ciBHVEEsIEJvcmRlcmxhbmRzIHVuZCBDaXZpbGl6YXRpb24gYmVrYW5udCBzaW5kLCBtaXQgNDEzLg0KDQojIyMgbmFjaCBWZXJrYXVmc3phaGxlbg0KYGBge3IgcGxvdChQdWJsaXNoZXJSYW5raW5nX0dsb2JhbCksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoUHVibGlzaGVyKSAlPiUgDQogIHN1bW1hcml6ZShBbnphaGwgPW4oKSxzdW0oR2xvYmFsX1NhbGVzKSkgJT4lDQogIGZpbHRlcihBbnphaGw+MTAwKSAlPiUNCnJlbmFtZSgNCiAgICBHbG9iYWxfU2FsZXMgPSAic3VtKEdsb2JhbF9TYWxlcykiDQogICAgKQ0KDQpQdWJsaXNoZXJTYWxlcyA8LSB2Z3NhbGVzICU+JSANCiAgZ3JvdXBfYnkoUHVibGlzaGVyKSAlPiUgDQogIHN1bW1hcml6ZShzdW0oR2xvYmFsX1NhbGVzKSkgJT4lDQpyZW5hbWUoDQogICAgR2xvYmFsX1NhbGVzID0gInN1bShHbG9iYWxfU2FsZXMpIg0KICAgICkgJT4lIGZpbHRlcihHbG9iYWxfU2FsZXM+MzAwKQ0KDQoNCg0KZ3JvdXBlZCA8LSBncm91cGVkICAlPiUgZmlsdGVyKFB1Ymxpc2hlciAlaW4lIFB1Ymxpc2hlclNhbGVzJFB1Ymxpc2hlcikNCmdyb3VwZWQkR2xvYmFsX1NhbGVzPC1hc192ZWN0b3IoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpDQpvcmRlcmVkIDwtIGdyb3VwZWRbb3JkZXIoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpLCBkZWNyZWFzaW5nID0gRkFMU0VdDQpvcmRlcmVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKG9yZGVyZWQkUHVibGlzaGVyLCAiRW50ZXJ0YWlubWVudCIpDQpvcmRlcmVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKG9yZGVyZWQkUHVibGlzaGVyLCAiSW50ZXJhY3RpdmUiKQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIlN0dWRpb3MiKQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIkdhbWVzIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwob3JkZXJlZCRQdWJsaXNoZXIsICJHYW1lIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtIGFzX2ZhY3RvcihvcmRlcmVkJFB1Ymxpc2hlcikNCg0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJQdWJsaXNoZXIiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIlZlcmvDpHVmZSAoaW4gbWlvKSINCg0KKQ0KDQoNCm9yZGVyZWQlPiUNCiAgcGxvdF9seSgpICU+JSANCiAgYWRkX2JhcnMoeD1+ZmN0X3Jlb3JkZXIoUHVibGlzaGVyLEdsb2JhbF9TYWxlcywgLmRlc2M9InRydWUiKSwNCiAgICAgICAgICAgeT1+R2xvYmFsX1NhbGVzLA0KICAgICAgICAgICBuYW1lPSJWZXJrYXVmc3phaGxlbiBwcm8gUHVibGlzaGVyIg0KICAgICAgICAgICAsY29sb3JzID0gbXlQYWxldHRlKSAlPiUgDQogIGxheW91dCh0aXRsZT0iVmVya2F1ZnN6YWhsZW4gcHJvIFB1Ymxpc2hlciIsDQogICAgICAgICB4YXhpcyA9IGF4LA0KICAgICAgICAgeWF4aXMgPSBheQ0KICAgICAgICAgKQ0KYGBgDQpCZWltIEJldHJhY2h0ZW4gZGVyIFZlcmthdWZzemFobGVuIGbDpGxsdCBoaWVyIGRpcmVrdCBkaWUgZGlza3JlcGFueiB6d2lzY2hlbiBBbnphaGwgZGVyIFNwaWVsZXJlbGVhc2VzIHVuZCBBbnphaGwgZGVyIFNwaWVsZXZlcmvDpHVmZSBhdWYuIEltIGdlZ2Vuc2F0eiB6dSBkZXIgQW56YWhsIGRlciBTcGllbGUgKGJlaSBkZW0gTmludGVuZG8gbnVyIGF1ZiBwbGF0eiA2IFNpdHopIGRvbWluaWVydCBOaW50ZW5kbygxLjc4NiBtcmQpIGluIFNhbGVzLiBFQSAoMS4xIG1yZCksIHdlbGNoZSBub2NoIG1pdCBBYnN0YW5kIGRpZSBtZWlzdGVuIHNwaWVscmVsZWFzZXMgaGF0dGVuIHNpbmQgaW4gZGVuIFZlcmvDpHVmZW4gbnVyIG5vY2ggbWl0IGRldXRsaWNoZW0gQWJzdGFuZCBhdWYgUGxhdHogMi4gQXVjaCBkaWUgYW5kZXJlbiBQbMOkdHplIHZlcsOkbmRlcm4gc2ljaCBsZWljaHQgZGllIFVudGVyc2NoaWVkZSBzaW5kIGhpZXIgamVkb2NoIGRldXRsaWNoIGdlcmluZ2VyIGFscyBiZWkgTmludGVuZG8gdW5kIEVBLiBJbnRlcmVzc2FudCB3w6RyZSBoaWVyenUgdmllbGxlaWNodCBub2NoIGVpbiBkaXJla3RlciB2ZXJnbGVpY2ggendpc2NoZW4gQW56YWhsIHVuZCBTYWxlcyBhYmVyIGdlbmF1ZXJlcyBkYXp1IGltIFtGYXppdF0oI0F1c2JsaWNrSW5EaWVadWt1bmZ0KQ0KDQojIyB7LX0NCg0KDQoNCioqKg0KDQojIFB1Ymxpc2hlciBSYW5raW5nIG5hY2ggUmVnaW9uIHsjUHVibGlzaGVyUmFua2luZ2J5UmVnaW9ufQ0KDQpOYWNoZGVtIHdpciB1bnMgZWluZW4gQWxsZ2VtZWluZW4gw5xiZXJibGljayDDvGJlciBkaWUgUHVibGlzaGVyIGdlbWFjaHQgaGFiZW4gYmV0cmFjaHRlbiB3aXIgZGllIFJlZ2lvbmFsZW4gdW50ZXJzY2hpZWRlIGluIGRlbiBWZXJrYXVmc3phaGxlbi4gSGllcnp1IHZlcndlbmRlbiB3aXIgZXJuZXV0IGRpZSBCZXJlaXRzIGJla2FubnRlbiBTaGVtYXRhIGRlciBbUGFyZXRvLV0oI1BsYXRmb3JtYW5hbHlzZSkgdW5kIFtLcmVpc2RpYWdyYW1tXSgjUGxhdGZvcm1SYW5raW5nQnlSZWdpb24pIGtvbWJvLiBFaW5lbiBSZWZyZXNoZXIgZsO8ciBkaWUgRXJzdGVsbHVuZyBlYmVuamVuZXIgRGlhZ3JhbW1lIGdpYnQgZXMgdmlhIGRlbiBFbnRzcHJlY2hlbmRlbiBMaW5rcy4NCg0KIyMgUmFua2luZyBuYWNoIFJlZ2lvbiB7LnRhYnNldH0NCiMjIyBCYWxrZW5kaWFncmFtbWUgey50YWJzZXR9DQojIyMjIEV1cm9wYQ0KDQpgYGB7ciBwbG90KFB1Ymxpc2hlclJhbmtpbmdfRVUxKSwgZWNobyA9IFRSVUUsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J21hcmt1cCcsIH0NCmdyb3VwZWQgPC0gdmdzYWxlcyAgJT4lIA0KICBncm91cF9ieShQdWJsaXNoZXIpICU+JSANCiAgc3VtbWFyaXplKEFuemFobCA9bigpLHN1bShFVV9TYWxlcykpICU+JQ0KICBmaWx0ZXIoQW56YWhsPjEwMCkgJT4lDQpyZW5hbWUoDQogICAgR2xvYmFsX1NhbGVzID0gInN1bShFVV9TYWxlcykiDQogICAgKQ0KDQpQdWJsaXNoZXJTYWxlcyA8LSB2Z3NhbGVzICU+JSANCiAgZ3JvdXBfYnkoUHVibGlzaGVyKSAlPiUgDQogIHN1bW1hcml6ZShzdW0oR2xvYmFsX1NhbGVzKSkgJT4lDQpyZW5hbWUoDQogICAgR2xvYmFsX1NhbGVzID0gInN1bShHbG9iYWxfU2FsZXMpIg0KICAgICkgJT4lIGZpbHRlcihHbG9iYWxfU2FsZXM+MzAwKQ0KDQoNCg0KZ3JvdXBlZCA8LSBncm91cGVkICAlPiUgZmlsdGVyKFB1Ymxpc2hlciAlaW4lIFB1Ymxpc2hlclNhbGVzJFB1Ymxpc2hlcikNCg0KDQpncm91cGVkJEdsb2JhbF9TYWxlczwtYXNfdmVjdG9yKGdyb3VwZWQkR2xvYmFsX1NhbGVzKQ0Kb3JkZXJlZCA8LSBncm91cGVkW29yZGVyKGdyb3VwZWQkR2xvYmFsX1NhbGVzKSwgZGVjcmVhc2luZyA9IEZBTFNFXQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIkVudGVydGFpbm1lbnQiKQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIkludGVyYWN0aXZlIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwob3JkZXJlZCRQdWJsaXNoZXIsICJTdHVkaW9zIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwob3JkZXJlZCRQdWJsaXNoZXIsICJHYW1lcyIpDQpvcmRlcmVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKG9yZGVyZWQkUHVibGlzaGVyLCAiR2FtZSIpDQpvcmRlcmVkJFB1Ymxpc2hlciA8LSBhc19mYWN0b3Iob3JkZXJlZCRQdWJsaXNoZXIpDQoNCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiUHVibGlzaGVyIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJFVSB2ZXJrw6R1ZmUgKGluIG1pbykiDQoNCikNCg0Kb3JkZXJlZCU+JQ0KICBwbG90X2x5KCkgJT4lIA0KICBhZGRfYmFycyh4PX5mY3RfcmVvcmRlcihQdWJsaXNoZXIsR2xvYmFsX1NhbGVzLCAuZGVzYz0idHJ1ZSIpLA0KICAgICAgICAgICB5PX5HbG9iYWxfU2FsZXMsDQogICAgICAgICAgIG5hbWU9IkVVIFZlcmthdWZzemFobGVuIHBybyBQdWJsaXNoZXIiDQogICAgICAgICAgICxjb2xvcnMgPSBteVBhbGV0dGUpICU+JSANCiAgbGF5b3V0KHRpdGxlPSJFVSBWZXJrYXVmc3phaGxlbiBwcm8gUHVibGlzaGVyIiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5DQogICAgICAgICApDQpgYGANCg0KSW0gdmVyZ2xlaWNoIHp1IGRlbiBHbG9iYWxlbiBWZXJrYXVmc3phaGxlbiBmw6RsbHQgaGllciBhdWYgZGFzIEVBICgzNzEuMjcgbWlvKSBkZXV0bGljaCBkaWNodGVyIGhpbnRlciBOaW50ZW5kbyg0MTguNzQpIGF1ZiBkZW0gWndlaXRlbiBQbGF0eiBpc3QuIERlciBBYnN0YW5kIHp3aXNjaGVuIEVBIHVuZCBBY3RpdmlzaW9uICgyMTUuNTMpIGlzdCBkZW1lbnRzcHJlY2hlbmQgYXVjaCBkZXV0bGljaCBncsO2w59lci4gRGllIHJlc3RsaWNoZW4gd2VydGUgdW50ZXJzY2hlaWRlbiBzaWNoIGFiZXIga2F1bS4NCg0KIyMjIyBOb3JkIEFtZXJpa2ENCmBgYHtyIHBsb3QoUHVibGlzaGVyUmFua2luZ19OQTEpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgDQogIGdyb3VwX2J5KFB1Ymxpc2hlcikgJT4lIA0KICBzdW1tYXJpemUoQW56YWhsID1uKCksc3VtKE5BX1NhbGVzKSkgJT4lDQogIGZpbHRlcihBbnphaGw+MTAwKSAlPiUNCnJlbmFtZSgNCiAgICBHbG9iYWxfU2FsZXMgPSAic3VtKE5BX1NhbGVzKSINCiAgICApDQoNClB1Ymxpc2hlclNhbGVzIDwtIHZnc2FsZXMgJT4lIA0KICBncm91cF9ieShQdWJsaXNoZXIpICU+JSANCiAgc3VtbWFyaXplKHN1bShHbG9iYWxfU2FsZXMpKSAlPiUNCnJlbmFtZSgNCiAgICBHbG9iYWxfU2FsZXMgPSAic3VtKEdsb2JhbF9TYWxlcykiDQogICAgKSAlPiUgZmlsdGVyKEdsb2JhbF9TYWxlcz4zMDApDQoNCg0KDQpncm91cGVkIDwtIGdyb3VwZWQgICU+JSBmaWx0ZXIoUHVibGlzaGVyICVpbiUgUHVibGlzaGVyU2FsZXMkUHVibGlzaGVyKQ0KDQpncm91cGVkJEdsb2JhbF9TYWxlczwtYXNfdmVjdG9yKGdyb3VwZWQkR2xvYmFsX1NhbGVzKQ0Kb3JkZXJlZCA8LSBncm91cGVkW29yZGVyKGdyb3VwZWQkR2xvYmFsX1NhbGVzKSwgZGVjcmVhc2luZyA9IEZBTFNFXQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIkVudGVydGFpbm1lbnQiKQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIkludGVyYWN0aXZlIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwob3JkZXJlZCRQdWJsaXNoZXIsICJTdHVkaW9zIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwob3JkZXJlZCRQdWJsaXNoZXIsICJHYW1lcyIpDQpvcmRlcmVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKG9yZGVyZWQkUHVibGlzaGVyLCAiR2FtZSIpDQpvcmRlcmVkJFB1Ymxpc2hlciA8LSBhc19mYWN0b3Iob3JkZXJlZCRQdWJsaXNoZXIpDQoNCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiUHVibGlzaGVyIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJOQSB2ZXJrw6R1ZmUgKGluIG1pbykiDQoNCikNCg0Kb3JkZXJlZCU+JQ0KICBwbG90X2x5KCkgJT4lIA0KICBhZGRfYmFycyh4PX5mY3RfcmVvcmRlcihQdWJsaXNoZXIsR2xvYmFsX1NhbGVzLCAuZGVzYz0idHJ1ZSIpLA0KICAgICAgICAgICB5PX5HbG9iYWxfU2FsZXMsDQogICAgICAgICAgIG5hbWU9Ik5BIFZlcmthdWZzemFobGVuIHBybyBQdWJsaXNoZXIiDQogICAgICAgICAgICxjb2xvcnMgPSBteVBhbGV0dGUpICU+JSANCiAgbGF5b3V0KHRpdGxlPSJOQSBWZXJrYXVmc3phaGxlbiBwcm8gUHVibGlzaGVyIiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5DQogICAgICAgICApDQpgYGANCg0KQXVjaCBpbiBOb3JkIEFtZXJpa2Ega2FubiBFQSg1OTUuMDcpIGxlaWNodCBncsO2w59lcmUgVmVya2F1ZnN6YWhsZW4gaW0gdmVyZ2xlaWNoIG1pdCBOaW50ZW5kbyAoODE2Ljg3KSBhbHMgbm9jaCBHbG9iYWwgdmVyYnVjaGVuLiBJbSBnZWdlbnNhdHogenUgRXVyb3BhIHNjaGVpbnQgamVkb2NoIEFjdGl2aXNpb24gKDQyOS43KSBpbiBBbWVyaWthIGRldXRsaWNoIGJlbGllYnRlciB6dSBzZWluLiBEaWUgd2VpdGVyZW4gUHVibGlzaGVyIHNpbmQgYXVjaCB3ZWl0ZXJoaW4gbmljaHQgUmVsZXZhbnQuDQoNCiMjIyMgSmFwYW4NCmBgYHtyIHBsb3QoUHVibGlzaGVyUmFua2luZ19KUDEpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgDQogIGdyb3VwX2J5KFB1Ymxpc2hlcikgJT4lIA0KICBzdW1tYXJpemUoQW56YWhsID1uKCksc3VtKEpQX1NhbGVzKSkgJT4lDQogIGZpbHRlcihBbnphaGw+MTAwKSAlPiUNCnJlbmFtZSgNCiAgICBHbG9iYWxfU2FsZXMgPSAic3VtKEpQX1NhbGVzKSINCiAgICApDQoNClB1Ymxpc2hlclNhbGVzIDwtIHZnc2FsZXMgJT4lIA0KICBncm91cF9ieShQdWJsaXNoZXIpICU+JSANCiAgc3VtbWFyaXplKHN1bShHbG9iYWxfU2FsZXMpKSAlPiUNCnJlbmFtZSgNCiAgICBHbG9iYWxfU2FsZXMgPSAic3VtKEdsb2JhbF9TYWxlcykiDQogICAgKSAlPiUgZmlsdGVyKEdsb2JhbF9TYWxlcz4zMDApDQoNCg0KDQpncm91cGVkIDwtIGdyb3VwZWQgICU+JSBmaWx0ZXIoUHVibGlzaGVyICVpbiUgUHVibGlzaGVyU2FsZXMkUHVibGlzaGVyKQ0KDQpncm91cGVkJEdsb2JhbF9TYWxlczwtYXNfdmVjdG9yKGdyb3VwZWQkR2xvYmFsX1NhbGVzKQ0Kb3JkZXJlZCA8LSBncm91cGVkW29yZGVyKGdyb3VwZWQkR2xvYmFsX1NhbGVzKSwgZGVjcmVhc2luZyA9IEZBTFNFXQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIkVudGVydGFpbm1lbnQiKQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIkludGVyYWN0aXZlIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwob3JkZXJlZCRQdWJsaXNoZXIsICJTdHVkaW9zIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwob3JkZXJlZCRQdWJsaXNoZXIsICJHYW1lcyIpDQpvcmRlcmVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKG9yZGVyZWQkUHVibGlzaGVyLCAiR2FtZSIpDQpvcmRlcmVkJFB1Ymxpc2hlciA8LSBhc19mYWN0b3Iob3JkZXJlZCRQdWJsaXNoZXIpDQoNCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiUHVibGlzaGVyIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJKUCB2ZXJrw6R1ZmUgKGluIG1pbykiDQoNCikNCg0Kb3JkZXJlZCU+JQ0KICBwbG90X2x5KCkgJT4lIA0KICBhZGRfYmFycyh4PX5mY3RfcmVvcmRlcihQdWJsaXNoZXIsR2xvYmFsX1NhbGVzLCAuZGVzYz0idHJ1ZSIpLA0KICAgICAgICAgICB5PX5HbG9iYWxfU2FsZXMsDQogICAgICAgICAgIG5hbWU9IkpQIFZlcmthdWZzemFobGVuIHBybyBQdWJsaXNoZXIiDQogICAgICAgICAgICxjb2xvcnMgPSBteVBhbGV0dGUpICU+JSANCiAgbGF5b3V0KHRpdGxlPSJKUCBWZXJrYXVmc3phaGxlbiBwcm8gUHVibGlzaGVyIiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5DQogICAgICAgICApDQpgYGANCg0KSmFwYW4gWmVpZ3QgaGllciB3b2hsIGRlbiBEZXV0bGljaHN0ZW4gdW50ZXJzY2hpZWQgYXVmLiBOaW50ZW5kbyAoNDU1LjQyKSBEb21pbmllcnQgaGllciBkaWUgVmVya2F1ZnN6YWhsZW4gbWl0IGRlciBtZWhyIGFscyA2IGZhY2hlbiBtZW5nZSBhbiB2ZXJrw6R1ZmVuIGFscyBTb255ICg3NC4xKSB3ZWxjaGUgc2ljaCBkZW4gMi4gUGxhdHogc2ljaGVybi4gRGllIGFuZGVyZW4gUHVibGlzaGVyIHNpbmQgYWxsZSBmYXN0IGdsZWljaCBpcnJlbGV2YW50IGluIEphcGFuLiANCg0KDQojIyMgS3JlaXNkaWFncmFtbWUgey50YWJzZXR9DQoNCiMjIyMgRXVyb3BhDQoNCmBgYHtyIHBsb3QoUHVibGlzaGVyUmFua2luZ19FVSksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoUHVibGlzaGVyKSAlPiUgDQogIHN1bW1hcml6ZShBbnphaGwgPW4oKSxzdW0oRVVfU2FsZXMpKSAlPiUNCiAgZmlsdGVyKEFuemFobD4xMDApICU+JQ0KcmVuYW1lKA0KICAgIEdsb2JhbF9TYWxlcyA9ICJzdW0oRVVfU2FsZXMpIg0KICAgICkNCg0KUHVibGlzaGVyU2FsZXMgPC0gdmdzYWxlcyAlPiUgDQogIGdyb3VwX2J5KFB1Ymxpc2hlcikgJT4lIA0KICBzdW1tYXJpemUoc3VtKEdsb2JhbF9TYWxlcykpICU+JQ0KcmVuYW1lKA0KICAgIEdsb2JhbF9TYWxlcyA9ICJzdW0oR2xvYmFsX1NhbGVzKSINCiAgICApICU+JSBmaWx0ZXIoR2xvYmFsX1NhbGVzPjMwMCkNCg0KDQoNCmdyb3VwZWQgPC0gZ3JvdXBlZCAgJT4lIGZpbHRlcihQdWJsaXNoZXIgJWluJSBQdWJsaXNoZXJTYWxlcyRQdWJsaXNoZXIpDQoNCmdyb3VwZWQkR2xvYmFsX1NhbGVzPC1hc192ZWN0b3IoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpDQpvcmRlcmVkIDwtIGdyb3VwZWRbb3JkZXIoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpLCBkZWNyZWFzaW5nID0gRkFMU0VdDQpvcmRlcmVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKG9yZGVyZWQkUHVibGlzaGVyLCAiRW50ZXJ0YWlubWVudCIpDQpvcmRlcmVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKG9yZGVyZWQkUHVibGlzaGVyLCAiSW50ZXJhY3RpdmUiKQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIlN0dWRpb3MiKQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIkdhbWVzIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwob3JkZXJlZCRQdWJsaXNoZXIsICJHYW1lIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtIGFzX2ZhY3RvcihvcmRlcmVkJFB1Ymxpc2hlcikNCg0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJQdWJsaXNoZXIiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIkVVIHZlcmvDpHVmZSAoaW4gbWlvKSINCg0KKQ0KDQpvcmRlcmVkJT4lDQogIHBsb3RfbHkoKSAlPiUgDQogIGFkZF9waWUodmFsdWVzID1+R2xvYmFsX1NhbGVzLGxhYmVscz1+UHVibGlzaGVyLA0KICAgICAgICAgICBuYW1lPSJFVSBWZXJrYXVmc3phaGxlbiBwcm8gUHVibGlzaGVyIg0KICAgICAgICAgICxjb2xvcnMgPSBteVBhbGV0dGUpICU+JSANCiAgbGF5b3V0KHRpdGxlPSJFVSBWZXJrYXVmc3phaGxlbiBwcm8gUHVibGlzaGVyIiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5DQogICAgICAgICApDQpgYGANCg0KSW0gdmVyZ2xlaWNoIHp1IGRlbiBHbG9iYWxlbiBWZXJrYXVmc3phaGxlbiBmw6RsbHQgaGllciBhdWYgZGFzIEVBICgyMy43JSkgZGV1dGxpY2ggZGljaHRlciBoaW50ZXIgTmludGVuZG8oMjYuNyUpIGF1ZiBkZW0gWndlaXRlbiBQbGF0eiBpc3QuIERlciBBYnN0YW5kIHp3aXNjaGVuIEVBIHVuZCBBY3RpdmlzaW9uICgxMy43JSkgaXN0IGRlbWVudHNwcmVjaGVuZCBhdWNoIGRldXRsaWNoIGdyw7bDn2VyLiBEaWUgcmVzdGxpY2hlbiB3ZXJ0ZSB1bnRlcnNjaGVpZGVuIHNpY2gga2F1bS4NCg0KIyMjIyBOb3JkLUFtZXJpa2ENCg0KYGBge3IgcGxvdChQdWJsaXNoZXJSYW5raW5nX05BMiksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoUHVibGlzaGVyKSAlPiUgDQogIHN1bW1hcml6ZShBbnphaGwgPW4oKSxzdW0oTkFfU2FsZXMpKSAlPiUNCiAgZmlsdGVyKEFuemFobD4xMDApICU+JQ0KcmVuYW1lKA0KICAgIEdsb2JhbF9TYWxlcyA9ICJzdW0oTkFfU2FsZXMpIg0KICAgICkNCg0KUHVibGlzaGVyU2FsZXMgPC0gdmdzYWxlcyAlPiUgDQogIGdyb3VwX2J5KFB1Ymxpc2hlcikgJT4lIA0KICBzdW1tYXJpemUoc3VtKEdsb2JhbF9TYWxlcykpICU+JQ0KcmVuYW1lKA0KICAgIEdsb2JhbF9TYWxlcyA9ICJzdW0oR2xvYmFsX1NhbGVzKSINCiAgICApICU+JSBmaWx0ZXIoR2xvYmFsX1NhbGVzPjMwMCkNCg0KDQoNCmdyb3VwZWQgPC0gZ3JvdXBlZCAgJT4lIGZpbHRlcihQdWJsaXNoZXIgJWluJSBQdWJsaXNoZXJTYWxlcyRQdWJsaXNoZXIpDQoNCmdyb3VwZWQkR2xvYmFsX1NhbGVzPC1hc192ZWN0b3IoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpDQpvcmRlcmVkIDwtIGdyb3VwZWRbb3JkZXIoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpLCBkZWNyZWFzaW5nID0gRkFMU0VdDQpvcmRlcmVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKG9yZGVyZWQkUHVibGlzaGVyLCAiRW50ZXJ0YWlubWVudCIpDQpvcmRlcmVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKG9yZGVyZWQkUHVibGlzaGVyLCAiSW50ZXJhY3RpdmUiKQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIlN0dWRpb3MiKQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIkdhbWVzIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwob3JkZXJlZCRQdWJsaXNoZXIsICJHYW1lIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtIGFzX2ZhY3RvcihvcmRlcmVkJFB1Ymxpc2hlcikNCg0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJQdWJsaXNoZXIiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIk5BIHZlcmvDpHVmZSAoaW4gbWlvKSINCg0KKQ0KDQpvcmRlcmVkJT4lDQogIHBsb3RfbHkoKSAlPiUgDQogIGFkZF9waWUodmFsdWVzID1+R2xvYmFsX1NhbGVzLGxhYmVscz1+UHVibGlzaGVyLHRleHRpbmZvPSdsYWJlbCtwZXJjZW50JywNCiAgICAgICAgICAgbmFtZT0iTkEgVmVya2F1ZnN6YWhsZW4gcHJvIFB1Ymxpc2hlciINCiAgICAgICAgICAsY29sb3JzID0gbXlQYWxldHRlKSAlPiUgDQogIGxheW91dCh0aXRsZT0iTkEgVmVya2F1ZnN6YWhsZW4gcHJvIFB1Ymxpc2hlciIsDQogICAgICAgICB4YXhpcyA9IGF4LA0KICAgICAgICAgeWF4aXMgPSBheQ0KICAgICAgICAgKQ0KYGBgDQoNCkF1Y2ggaW4gTm9yZCBBbWVyaWthIGthbm4gRUEoMjEuMyUpIGxlaWNodCBncsO2w59lcmUgVmVya2F1ZnN6YWhsZW4gaW0gdmVyZ2xlaWNoIG1pdCBOaW50ZW5kbyAoMjkuMyUpIGFscyBub2NoIEdsb2JhbCB2ZXJidWNoZW4gZGllc2Ugc2luZCBqZWRvY2ggZ2VyaW5nZXIgYWxzIG5vY2ggaW4gRXVyb3BhLiBJbSBnZWdlbnNhdHogenUgRXVyb3BhIHNjaGVpbnQgamVkb2NoIEFjdGl2aXNpb24gKDE1LjQlKSBpbiBBbWVyaWthIGRldXRsaWNoIGJlbGllYnRlciB6dSBzZWluLiBEaWUgd2VpdGVyZW4gUHVibGlzaGVyIHNpbmQgYXVjaCB3ZWl0ZXJoaW4gbmljaHQgUmVsZXZhbnQuDQoNCiMjIyMgSmFwYW4NCg0KYGBge3IgcGxvdChQdWJsaXNoZXJSYW5raW5nX0pQMiksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoUHVibGlzaGVyKSAlPiUgDQogIHN1bW1hcml6ZShBbnphaGwgPW4oKSxzdW0oSlBfU2FsZXMpKSAlPiUNCiAgZmlsdGVyKEFuemFobD4xMDApICU+JQ0KcmVuYW1lKA0KICAgIEdsb2JhbF9TYWxlcyA9ICJzdW0oSlBfU2FsZXMpIg0KICAgICkNCg0KUHVibGlzaGVyU2FsZXMgPC0gdmdzYWxlcyAlPiUgDQogIGdyb3VwX2J5KFB1Ymxpc2hlcikgJT4lIA0KICBzdW1tYXJpemUoc3VtKEdsb2JhbF9TYWxlcykpICU+JQ0KcmVuYW1lKA0KICAgIEdsb2JhbF9TYWxlcyA9ICJzdW0oR2xvYmFsX1NhbGVzKSINCiAgICApICU+JSBmaWx0ZXIoR2xvYmFsX1NhbGVzPjMwMCkNCg0KDQoNCmdyb3VwZWQgPC0gZ3JvdXBlZCAgJT4lIGZpbHRlcihQdWJsaXNoZXIgJWluJSBQdWJsaXNoZXJTYWxlcyRQdWJsaXNoZXIpDQoNCmdyb3VwZWQkR2xvYmFsX1NhbGVzPC1hc192ZWN0b3IoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpDQpvcmRlcmVkIDwtIGdyb3VwZWRbb3JkZXIoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpLCBkZWNyZWFzaW5nID0gRkFMU0VdDQpvcmRlcmVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKG9yZGVyZWQkUHVibGlzaGVyLCAiRW50ZXJ0YWlubWVudCIpDQpvcmRlcmVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKG9yZGVyZWQkUHVibGlzaGVyLCAiSW50ZXJhY3RpdmUiKQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIlN0dWRpb3MiKQ0Kb3JkZXJlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChvcmRlcmVkJFB1Ymxpc2hlciwgIkdhbWVzIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwob3JkZXJlZCRQdWJsaXNoZXIsICJHYW1lIikNCm9yZGVyZWQkUHVibGlzaGVyIDwtIGFzX2ZhY3RvcihvcmRlcmVkJFB1Ymxpc2hlcikNCg0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJQdWJsaXNoZXIiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIkpQIHZlcmvDpHVmZSAoaW4gbWlvKSINCg0KKQ0KDQpvcmRlcmVkJT4lDQogIHBsb3RfbHkoKSAlPiUgDQogIGFkZF9waWUodmFsdWVzID1+R2xvYmFsX1NhbGVzLGxhYmVscz1+UHVibGlzaGVyLA0KICAgICAgICAgICBuYW1lPSJKUCBWZXJrYXVmc3phaGxlbiBwcm8gUHVibGlzaGVyIg0KICAgICAgICAgICxjb2xvcnMgPSBteVBhbGV0dGUpICU+JSANCiAgbGF5b3V0KHRpdGxlPSJKUCBWZXJrYXVmc3phaGxlbiBwcm8gUHVibGlzaGVyIiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5DQogICAgICAgICApDQpgYGANCg0KSmFwYW4gWmVpZ3QgaGllciB3b2hsIGRlbiBEZXV0bGljaHN0ZW4gdW50ZXJzY2hpZWQgYXVmLiBOaW50ZW5kbyAoODAuMSUpIERvbWluaWVydCBoaWVyIGRpZSBWZXJrYXVmc3phaGxlbiBtaXQgZGVyIG1laHIgYWxzIDYgZmFjaGVuIG1lbmdlIGFuIHZlcmvDpHVmZW4gYWxzIFNvbnkgKDEzJSkgd2VsY2hlIHNpY2ggZGVuIDIuIFBsYXR6IHNpY2hlcm4uIERpZSBhbmRlcmVuIFB1Ymxpc2hlciBzaW5kIG1pdCB3ZW5pZ2VyIGFscyAyLjUlIGFsbGUgZmFzdCBnbGVpY2ggaXJyZWxldmFudCBpbiBKYXBhbi4gDQoNCiMjIHstfQ0KDQpad2lzY2hlbiBFVSB1bmQgVVMgbGFzc2VuIHNpY2ggaGllciBrYXVtIFVudGVyc2NoaWVkZSBmZXN0c3RlbGxlbiBpbiBKYXBhbiBoaW5nZWdlbiBpc3QgZWluZSBkZXV0bGljaGUgdmVyc2NoaWVidW5nIHp1IGVya2VubmVuLiBKYXBhbmlzY2hlIFB1Ymxpc2hlciBmw7xocmVuIGhpZXJiZWkgZGllIExpc3RlIGFuIHVuZCBkcsOkbmdlbiBhbmRlcmUgZ3Jvw59lIHVudGVybmVobWVuIHZvbiBkZW4gVG9wIHNwb3RzLiBEZW1lbnRzcHJlY2hlbmQga8O2bm5lbiB3aXIgc2NobHVzc2ZvbGdlcm4gZGFzIG1hbmNoZSBSZWdpb25lbiwgdm9yYWxsZW0gSmFwYW4gd2VsY2hlcyBkaWUga2xlaW5zdGUgUmVnaW9uIGlzdCwgZGV1dGxpY2hlIHZvcmxpZWJlbiBpbiBzcGllbGVuIGJlc3RpbW10ZXIgUHVibGlzaGVyIGhhYmVuLCB3ZWxjaGUgdm9uIGRlciBHbG9iYWxlbiBub3JtIEFid2VpY2hlbi4gRWluZSBHZW5hdWVyZSBBbmFseXNlIHZvbiBFdXJvcGEgdW5kIE5vcmQgQW1lcmlrYSBkdXJjaCB1bnRlcnRlaWx1bmcgaW4gTMOkbmRlci9TdGFhdGVuIHfDpGhyZSBoaWVyIHZlcm11dGxpY2ggZGV1dGxpY2ggaW50ZXJlc3NhbnRlciB3aXJkIHZvbiBkZW4gRGF0ZW4gamVkb2NoIGxlaWRlciBuaWNodCBhbmdlYm90ZW4uDQoNCioqKg0KDQojIEdlbnJldmVydGVpbHVuZyBkZXIgVmlkZW9zcGllbGUgbmFjaCBBbnphaGwgeyNHZW5yZUFtb3VudEdsb2JhbH0NCg0KRGEgd2lyIHVucyBudSBrbGFyIGdld29yZGVuIHNpbmQsIGRhc3MgZXMgYmVzdGltbXRlIFB1Ymxpc2hlciBnaWJ0LCBkaWUgYmVsaWVidGVyIHNpbmQgYWxzIGFuZGVyZSB3w6RyZSBlcyBpbnRlcmVzc2FudCBoZXJhdXN6dWZpbmRlbiBvYiBiZXN0aW1tdGUgU3BpZWxlIEdlbnJlcyBiZWxpZWJ0ZXIgc2luZCBhbHMgYW5kZXJlLiBIaWVyenUgdmVyZ2xlaWNoZW4gd2lyIHp1ZXJzdCBlaW5tYWwgZGllIEdlbnJlcyBuYWNoIGFuemFobCBkZXIgU3BpZWxlcmVsZWFzZXMgdW5kIHZlcndlbmRlbiBlcm5ldXQgZWluIFtQYXJldG8tXSgjUGxhdGZvcm1hbmFseXNlKSB1bmQgW0tyZWlzZGlhZ3JhbW1dKCNQbGF0Zm9ybVJhbmtpbmdCeVJlZ2lvbikuIEFuenVtZXJrZW4gaXN0IGhpZXJiZWkgamVkb2NoIGRhcyBTcGllbGUgbWVpc3QgbWVociBhbHMgZWluZW0gR2VucmUgYW5nZWjDtnJlbiBpbiBkaWVzZW0gRGF0ZW5zYXR6IGlzdCBqZWRvY2ggaW1tZXIgbnVyIGVpbnMgYW5nZWdlYmVuLg0KDQojIyBHZW5yZSBuYWNoIEFuemFobCB7LnRhYnNldH0NCg0KIyMjIEJhbGtlbmRpYWdyYW1tDQoNCmBgYHtyIHBsb3QoR2VucmVBbW91bnRfR0xvYmFsMSksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoR2VucmUpICU+JSANCiAgc3VtbWFyaXplKEFuemFobCA9bigpKQ0KDQpncm91cGVkJEFuemFobDwtYXNfdmVjdG9yKGdyb3VwZWQkQW56YWhsKQ0Kb3JkZXJlZCA8LSBncm91cGVkW29yZGVyKGdyb3VwZWQkQW56YWhsKSwgZGVjcmVhc2luZyA9IEZBTFNFXQ0Kb3JkZXJlZCRHZW5yZSA8LSBhc19mYWN0b3Iob3JkZXJlZCRHZW5yZSkNCg0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJHZW5yZSINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiQW56YWhsIg0KDQopDQoNCm9yZGVyZWQlPiUNCiAgcGxvdF9seSgpICU+JSANCiAgYWRkX2JhcnMoeD1+ZmN0X3Jlb3JkZXIoR2VucmUsQW56YWhsLCAuZGVzYz0idHJ1ZSIpLA0KICAgICAgICAgICB5PX5BbnphaGwsDQogICAgICAgICAgIG5hbWU9IlZpZGVvc3BpZWxhbnphaGwgbmFjaCBHZW5yZSINCiAgICAgICAgICAgLGNvbG9ycyA9IG15UGFsZXR0ZSkgJT4lIA0KICBsYXlvdXQodGl0bGU9IlZpZGVvc3BpZWxhbnphaGwgbmFjaCBHZW5yZSIsDQogICAgICAgICB4YXhpcyA9IGF4LA0KICAgICAgICAgeWF4aXMgPSBheQ0KICAgICAgICAgKQ0KDQpgYGANCg0KRGVyIEFuZsO8aHJlciBkZXIgTGlzdGUgaXN0IG1pdCBkZXV0bGljaGVtIEFic3RhbmQgQWN0aW9uIChHVEEsQmxvb2Rib3JuZSkgbWl0IDMzMTYuIEF1ZiBkZW0gWndlaXRlbiBwbGF0eiBmaW5kZXQgc2ljaCBTcG9ydHMgKDIzNDYpIG1pdCByZWloZW4gd2llIEZJRkEgdW5kIE5CQTJrLiBEZW4gZHJpdHRlbiBQbGF0eiBiZWxlZ3QgZWluIEdlbnJlIGRhcyBhdXMgdmllbGVuIHZlcnNjaGllZGVuZW4gR2VucmVuIGJlc3RlaHQgZGllIGluIGRpZXNlciBMaXN0ZSBuaWNodCBhdWZnZWbDvGhydCB3ZXJkZW4gbWl0IDE3MzkuIE1pc2MgYmVpbmhhbHRldCBzcGllbGUgd2llIEp1c3QgRGFuY2UgKE11c2lrL1JoeXRobXVzKSBvZGVyIE1pbmVjcmFmdCBlaW4gU2FuZGJveCBTdXJ2aXZhbCBnYW1lLiBEYW5hY2gga29tbWVuIG1pdCBnZXJpbmdlcmVtIEFic3RhbmQgZGVyIFJlaWhlIG5hY2ggUm9sZS1QbGF5aW5nIChXaXRjaGVyLCBUaGUgRWxkZXIgU2Nyb2xscykgbWl0IDE0ODgsIFNob290ZXIgKENhbGwgb2YgRHV0eSwgRG9vbSkgbWl0IDEzMTAsIEFkdmVudHVyZSAoR29kIG9mIFdhciwgTGlmZSBpcyBTdHJhbmdlKSBtaXQgMTI4NiB1bmQgUmFjaW5nIChHcmFuIFRvdXJpc21vLCBGb3J6YSkgbWl0IDEyNDkuIERhbmFjaCBmb2xnZW4gbWl0IGVpbmVtIGdyw7bDn2VyZW4gQWJzdGFuZCBQbGF0Zm9ybSAoU3VwZXIgTWFyaW8sIExpdHRsZUJpZ1BsYW5ldCkgbWl0IDg4NiwgU2ltdWxhdGlvbiAoU2ltcywgTWljcm9zb2Z0IEZsaWdodCBTaW11bGF0b3IpIG1pdCA4Njcgc293aWUgRmlnaHRpbmcgKFRla2tlbiwgU3VwZXIgU21hc2ggQnJvcykgbWl0IDg4NC4gWnUgZ3V0ZXIgbGV0enQgZmVobGVuIG5vY2ggU3RyYXRlZ3kgKEFnZSBvZiBFbXBpcmVzLCBDaXZpbGlzYXRpb24pIG1pdCA2ODEgc293aWUgUHV6emxlIChQb3J0YWwsVGV0cmlzKSBtaXQgNTgyLg0KDQojIyMgS3JlaXNkaWFncmFtbQ0KDQpgYGB7ciBwbG90KEdlbnJlQW1vdW50X0dMb2JhbDIpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgDQogIGdyb3VwX2J5KEdlbnJlKSAlPiUgDQogIHN1bW1hcml6ZShBbnphaGwgPW4oKSkNCg0KZ3JvdXBlZCRBbnphaGw8LWFzX3ZlY3Rvcihncm91cGVkJEFuemFobCkNCm9yZGVyZWQgPC0gZ3JvdXBlZFtvcmRlcihncm91cGVkJEFuemFobCksIGRlY3JlYXNpbmcgPSBGQUxTRV0NCm9yZGVyZWQkR2VucmUgPC0gYXNfZmFjdG9yKG9yZGVyZWQkR2VucmUpDQoNCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiR2VucmUiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIkFuemFobCINCg0KKQ0KDQpvcmRlcmVkJT4lDQogIHBsb3RfbHkoKSAlPiUgDQogIGFkZF9waWUodmFsdWVzID1+QW56YWhsLGxhYmVscz1+R2VucmUsDQogICAgICAgICAgIG5hbWU9IlZpZGVvc3BpZWxhbnphaGwgbmFjaCBHZW5yZSINCiAgICAgICAgICAsY29sb3JzID0gbXlQYWxldHRlKSAlPiUgDQogIGxheW91dCh0aXRsZT0iVmlkZW9zcGllbGFuemFobCBuYWNoIEdlbnJlIiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5DQogICAgICAgICApDQpgYGANCg0KRGVyIEFuZsO8aHJlciBkZXIgTGlzdGUgaXN0IG1pdCBkZXV0bGljaGVtIEFic3RhbmQgQWN0aW9uIChHVEEsQmxvb2Rib3JuZSkgbWl0IDIwJS4gQXVmIGRlbSBad2VpdGVuIHBsYXR6IGZpbmRldCBzaWNoIFNwb3J0cyAoMTQuMSUpIG1pdCByZWloZW4gd2llIEZJRkEgdW5kIE5CQTJrLiBEZW4gZHJpdHRlbiBQbGF0eiBiZWxlZ3QgZWluIEdlbnJlIGRhcyBhdXMgdmllbGVuIHZlcnNjaGllZGVuZW4gR2VucmVuIGJlc3RlaHQgZGllIGluIGRpZXNlciBMaXN0ZSBuaWNodCBhdWZnZWbDvGhydCB3ZXJkZW4gbWl0IDEwLjUlLiBNaXNjIGJlaW5oYWx0ZXQgc3BpZWxlIHdpZSBKdXN0IERhbmNlIChNdXNpay9SaHl0aG11cykgb2RlciBNaW5lY3JhZnQgZWluIFNhbmRib3ggU3Vydml2YWwgZ2FtZS4gRGFuYWNoIGtvbW1lbiBtaXQgZ2VyaW5nZXJlbSBBYnN0YW5kIGRlciBSZWloZSBuYWNoIFJvbGUtUGxheWluZyAoV2l0Y2hlciwgVGhlIEVsZGVyIFNjcm9sbHMpIG1pdCA4Ljk2JSwgU2hvb3RlciAoQ2FsbCBvZiBEdXR5LCBEb29tKSBtaXQgNy44OSUsIEFkdmVudHVyZSAoR29kIG9mIFdhciwgTGlmZSBpcyBTdHJhbmdlKSBtaXQgNy43NSUgdW5kIFJhY2luZyAoR3JhbiBUb3VyaXNtbywgRm9yemEpIG1pdCA3LjUzJS4gRGFuYWNoIGZvbGdlbiBtaXQgZWluZW0gZ3LDtsOfZXJlbiBBYnN0YW5kIFBsYXRmb3JtIChTdXBlciBNYXJpbywgTGl0dGxlQmlnUGxhbmV0KSBtaXQgNS4zNCUsIFNpbXVsYXRpb24gKFNpbXMsIE1pY3Jvc29mdCBGbGlnaHQgU2ltdWxhdG9yKSBtaXQgNS4yMiUgc293aWUgRmlnaHRpbmcgKFRla2tlbiwgU3VwZXIgU21hc2ggQnJvcykgbWl0IDUuMTElLiBadSBndXRlciBsZXR6dCBmZWhsZW4gbm9jaCBTdHJhdGVneSAoQWdlIG9mIEVtcGlyZXMsIENpdmlsaXNhdGlvbikgbWl0IDQuMSUgc293aWUgUHV6emxlIChQb3J0YWwsVGV0cmlzKSBtaXQgMy41MSUuDQoNCiMjIHstfQ0KDQpBdWZmw6RsbGlnIGhpZXJiZWkgaXN0IGRhcyBkaWUgR3LDtsOfdGVuIHZpZXIgR2VucmVzIDUzLjU2JSBkZXIgU3BpZWxlcmVsZWFzZXMgYXVzbWFjaGVuLiBEaWVzIGlzdCBhbnNpY2ggbmljaHQgd2VpdGVyIFZlcnd1bmRlcmxpY2guIEluIGRlciBTcGllbGVpbmR1c3RyaWUgYnp3IGFsbGdlbWVpbiwgaXN0IGVzIGVpbiBnZXJuZSBnZW51dHp0ZXMga29uemVwdCBGdW5rdGlvbmllcmVuZGUgZGluZ2UgenUgw7xiZXJuZWhtZW4uIERpZXMgaXN0IHZvcmFsbGVtIGF1ZmbDpGxsaWcgYmVpIFNwaWVsZW4sIHdlbGNoZSBnYW56ZSBHZW5yZXMgcHLDpGdlbi4gU2VpIGVzIE1pbmVjcmFmdCBmw7xyIGRpZSBTdXJ2aXZhbCBHYW1lcyAoRGF5WiwgUnVzdCksIFdvcmxkIG9mIFdhcmNyYWZ0IGbDvHIgZGllIE1NT1JQRydzIChGaW5hbCBGYW50YXN5IDE0LCBHdWlsZCBXYXJzIDIpIG9kZXIgZGllIFdhcmNyYWZ0IDMgbW9kIERvdGEgd2VsY2hlIGRhcyBNT0JBIGdlbnJlIChMZWFndWUgb2YgTGVnZW5kcywgRG90YSAyKSBuYWNoIHNpY2ggZ2V6b2dlbiBoYXQuDQoNCioqKg0KDQojIEdlbnJldmVydGVpbHVuZyBkZXIgVmlkZW9zcGllbGUgbmFjaCBWZXJrYXVmc3phaGxlbiB7I0dlbnJlU2FsZXNHbG9iYWx9DQoNClNjaGF1ZW4gd2lyIHVucyBudW4gamVkb2NoIGFuIG9iIGRpZSBWZXJrYXVmc3phaGxlbiBkaWUgZ2xlaWNoZW4gaMOkdWZ1bmdlbiBhdWZ6ZWlnZW4gdW5kIHZlcndlbmRlbiB3aWVkZXIgZWluIFtQYXJldG8tXSgjUGxhdGZvcm1hbmFseXNlKSB1bmQgW0tyZWlzZGlhZ3JhbW1dKCNQbGF0Zm9ybVJhbmtpbmdCeVJlZ2lvbikuIEVzIGdpbHQgd2VpdGVyaGluIGRpZSBvYmVuZ2VuYW5udGUgUHJvYmxlbWF0aWsgZGVyIEdlbnJlbm90YXRpb24gZGVzIERhdGVuc2F0emVzLg0KDQojIyBWZXJrYXVmc3phaGxlbiB7LnRhYnNldH0NCg0KIyMjIEJhbGtlbmRpYWdyYW1tDQoNCmBgYHtyIHBsb3QoU2FsZXNCeUdlbnJlX0dsb2JhbDEpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KDQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoR2VucmUpICU+JSANCiAgc3VtbWFyaXplKHN1bShHbG9iYWxfU2FsZXMpKSAgJT4lDQpyZW5hbWUoDQogICAgR2xvYmFsX1NhbGVzID0gInN1bShHbG9iYWxfU2FsZXMpIg0KICAgICkNCmdyb3VwZWQkR2xvYmFsX1NhbGVzPC1hc192ZWN0b3IoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpDQpvcmRlcmVkIDwtIGdyb3VwZWRbb3JkZXIoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpLCBkZWNyZWFzaW5nID0gRkFMU0VdDQoNCmF4IDwtIGxpc3QoDQogIHRpdGxlID0gIkdlbnJlIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJWZXJrw6R1ZmUgKGluIG1pbykiDQoNCikNCg0Kb3JkZXJlZCU+JQ0KICBwbG90X2x5KCkgJT4lIA0KICBhZGRfYmFycyh4PX5mY3RfcmVvcmRlcihHZW5yZSxHbG9iYWxfU2FsZXMsIC5kZXNjPSJ0cnVlIiksDQogICAgICAgICAgIHk9fkdsb2JhbF9TYWxlcywNCiAgICAgICAgICAgbmFtZT0iVmVya2F1ZnN6YWhsZW4gbmFjaCBHZW5yZSINCiAgICAgICAgICAgLGNvbG9ycyA9IG15UGFsZXR0ZSkgJT4lIA0KICBsYXlvdXQodGl0bGU9IlZlcmthdWZzemFobGVuIG5hY2ggR2VucmUiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgICkNCg0KYGBgDQoNCkF1ZiBQbGF0eiAxIHVuZCAyIGRlciBMaXN0ZSBiZWZpbmRlbiBzaWNoIHdlaXRlcmhpbiBBY3Rpb24gKDEuNzUxIG1yZCkgdW5kIFNwb3RzICgxLjMzIG1yZCkuIFBsYXR6IDMgYmVsZWd0IGhpZXIgamVkb2NoIG5pY2h0IE1pc2Mgd2VsY2hlcyBtaXQgODA5Ljk2IG1pbyBhdWYgcGxhdHogNiBhYmdlcnV0c2NodCBpc3Qgc29uZGVybiBTaG9vdGVyICgxLjAzNyBtcmQpLiBQbGF0eiA0IHdpcmQgd2VpdGVyaGluIHZvbiBSb2xlLVBsYXlpbmcgKDkyNy4zNyBtaW8pIGJlbGVndC4gQXVjaCBQbGF0Zm9ybSAoODMxLjM3KSB2ZXJrYXVmZW4gc2ljaCBkZXV0bGljaCBiZXNzZXIgdW5kIHNpY2hlcm4gc2ljaCBQbGF0eiA1LiBEaWUgcmVzdGxpY2hlbiBHZW5yZXMgdW50ZXJzY2hlaWRlbiBzaWNoIEthdW0gaW4gQW56YWhsIHVuZCBWZXJrYXVmc3phaGxlbi4NCg0KDQojIyMgS3JlaXNkaWFncmFtbQ0KDQpgYGB7ciBwbG90KFNhbGVzQnlHZW5yZV9HbG9iYWwyKSwgZWNobyA9IFRSVUUsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J21hcmt1cCcsIH0NCg0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgDQogIGdyb3VwX2J5KEdlbnJlKSAlPiUgDQogIHN1bW1hcml6ZShzdW0oR2xvYmFsX1NhbGVzKSkgICU+JQ0KcmVuYW1lKA0KICAgIEdsb2JhbF9TYWxlcyA9ICJzdW0oR2xvYmFsX1NhbGVzKSINCiAgICApDQpncm91cGVkJEdsb2JhbF9TYWxlczwtYXNfdmVjdG9yKGdyb3VwZWQkR2xvYmFsX1NhbGVzKQ0Kb3JkZXJlZCA8LSBncm91cGVkW29yZGVyKGdyb3VwZWQkR2xvYmFsX1NhbGVzKSwgZGVjcmVhc2luZyA9IEZBTFNFXQ0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJHZW5yZSINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiVmVya8OkdWZlIChpbiBtaW8pIg0KDQopDQoNCm9yZGVyZWQlPiUNCiAgcGxvdF9seSgpICU+JSANCiAgYWRkX3BpZSh2YWx1ZXMgPX5HbG9iYWxfU2FsZXMsbGFiZWxzPX5HZW5yZSwNCiAgICAgICAgICAgbmFtZT0iVmVya2F1ZnN6YWhsZW4gbmFjaCBHZW5yZSINCiAgICAgICAgICAsY29sb3JzID0gbXlQYWxldHRlKSAlPiUgDQogIGxheW91dCh0aXRsZT0iVmVya2F1ZnN6YWhsZW4gbmFjaCBHZW5yZSIsDQogICAgICAgICB4YXhpcyA9IGF4LA0KICAgICAgICAgeWF4aXMgPSBheQ0KICAgICAgICApDQpgYGANCg0KQXVmIFBsYXR6IDEgdW5kIDIgZGVyIExpc3RlIGJlZmluZGVuIHNpY2ggd2VpdGVyaGluIEFjdGlvbiAoMTkuNiUpIHVuZCBTcG90cyAoMTQuOSUpLiBQbGF0eiAzIGJlbGVndCBoaWVyIGplZG9jaCBuaWNodCBNaXNjIHdlbGNoZXMgbWl0IDkuMDglIGF1ZiBwbGF0eiA2IGFiZ2VydXRzY2h0IGlzdCBzb25kZXJuIFNob290ZXIgKDExLjYlKS4gUGxhdHogNCB3aXJkIHdlaXRlcmhpbiB2b24gUm9sZS1QbGF5aW5nICgxMC40JSkgYmVsZWd0LiBBdWNoIFBsYXRmb3JtICg5LjMyJSkgdmVya2F1ZmVuIHNpY2ggZGV1dGxpY2ggYmVzc2VyIHVuZCBzaWNoZXJuIHNpY2ggUGxhdHogNS4gRGllIHJlc3RsaWNoZW4gR2VucmVzIHVudGVyc2NoZWlkZW4gc2ljaCBLYXVtIGluIEFuemFobCB1bmQgVmVya2F1ZnN6YWhsZW4uDQoNCiMjIHstfQ0KDQpCZWltIEJldHJhY2h0ZW4gZsOkbGx0IGhpZXIgYXVmLCBkYXNzIHNpY2ggZWluaWdlIEdlbnJlcyBkZXV0bGljaCBiZXNzZXIgdmVya2F1ZmVuIGFscyBhbmRlcmUuIFZvcmFsbGVtIFNob290ZXIgdW5kIFBsYXRmb3JtIHNwaWVsZSBzaW5kIGhpZXIgZGllIEthc3NlbnNjaGxhZ2VyIHdlbm4gbWFuIGRpZSBWZXJrYXVmc3phaGxlbiBtaXQgQW56YWhsIGRlciBTcGllbGUgdmVyZ2xlaWNodC4gRGllIGdyb8OfZW4gR2VucmVzIEFjdGlvbiB1bmQgU3BvcnRzIHNpbmQgamVkb2NoIHNvd29obCBpbiB2ZXJrYXVmc3phaGxlbiBhbHMgYXVjaCBBbnphaGwgZGVyIFNwaWVsZSB1bmFuZ2Vmb2NodGVuIGF1ZiBwbGF0eiAxIHVuZCAyLg0KDQoqKioNCg0KIyBSZWdpb25hbGUgVW50ZXJzY2hpZWRlIGRlciBHZW5yZXMgeyNHZW5yZUFtb3VudEJ5UmVnaW9ufQ0KDQpOYWNoZGVtIHdpciB2b3JoaW4gYmVpIGRlbiBbUGxhdGZvcm1lbl0oI1BsYXRmb3JtUmFua2luZ0J5UmVnaW9uKSBkZXV0bGljaGUgUmVnaW9uYWxlIFVudGVyc2NoaWVkZSBmZXN0c3RlbGxlbiBrb25udGVuIHN0ZWxsdCBzaWNoIGJlaSBkZW4gR2VucmVzIGRpZSBnbGVpY2hlIEZyYWdlIHVuZCBkZW1lbnRzcHJlY2hlbmQgYXVjaCB3aWVkZXIgZGVyIGdsZWljaGUgTMO2c3VuZ3NhbnNhdHogbWl0IFtQYXJldG8tXSgjUGxhdGZvcm1hbmFseXNlKSB1bmQgW0tyZWlzZGlhZ3JhbW1lbl0oI1BsYXRmb3JtUmFua2luZ0J5UmVnaW9uKS4NCg0KIyMgVmVya8OkdWZlIHBybyBHZW5yZSB7LnRhYnNldH0NCg0KIyMjIEJhbGtlbmRpYWdyYW1tZSB7LnRhYnNldH0NCg0KIyMjIyBFdXJvcGENCg0KYGBge3IgcGxvdChTYWxlc0J5R2VucmVfRVUxKSwgZWNobyA9IFRSVUUsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J21hcmt1cCcsIH0NCg0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgDQogIGdyb3VwX2J5KEdlbnJlKSAlPiUgDQogIHN1bW1hcml6ZShzdW0oRVVfU2FsZXMpKSAgJT4lDQpyZW5hbWUoDQogICAgR2xvYmFsX1NhbGVzID0gInN1bShFVV9TYWxlcykiDQogICAgKQ0KZ3JvdXBlZCRHbG9iYWxfU2FsZXM8LWFzX3ZlY3Rvcihncm91cGVkJEdsb2JhbF9TYWxlcykNCm9yZGVyZWQgPC0gZ3JvdXBlZFtvcmRlcihncm91cGVkJEdsb2JhbF9TYWxlcyksIGRlY3JlYXNpbmcgPSBGQUxTRV0NCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiR2VucmUiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIlZlcmvDpHVmZSAoaW4gbWlvKSINCg0KKQ0KDQpvcmRlcmVkJT4lDQogIHBsb3RfbHkoKSAlPiUgDQogIGFkZF9iYXJzKHg9fmZjdF9yZW9yZGVyKEdlbnJlLEdsb2JhbF9TYWxlcywgLmRlc2M9InRydWUiKSwNCiAgICAgICAgICAgeT1+R2xvYmFsX1NhbGVzLA0KICAgICAgICAgICBuYW1lPSJWZXJrYXVmc3phaGxlbiBuYWNoIEdlbnJlIChFVSkiDQogICAgICAgICAgICxjb2xvcnMgPSBteVBhbGV0dGUpICU+JSANCiAgbGF5b3V0KHRpdGxlPSJWZXJrYXVmc3phaGxlbiBuYWNoIEdlbnJlIChFVSkiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgICkNCmBgYA0KRXVyb3BhIHNpZWh0IHdpZSBiZXJlaXRzIGluIGRlciBbUGxhdGZvcm1hbmFseXNlXSgjUGxhdGZvcm1SYW5raW5nQnlSZWdpb24pIGZlc3RnZXN0ZWxsdCBkZW0gR2xvYmFsZW4gR2VucmV2ZXJnbGVpY2ggcmVjaHQgw6RobmxpY2guIEFjdGlvbiAoNTI1IG1pbykgZsO8aHJ0IHdlaXRlcmhpbiB2b3IgU3BvcnRzKDM3Ni44NSBtaW8pIHVuZCBTaG9vdGVybiAoMzEzLjI3IG1pbykuIEF1ZiBwbGF0eiA0IGlzdCBkYW5uIGRlciBlcnN0ZSBVbnRlcnNjaGllZCBmZXN0c3RlbGxiYXIuIEFuc3RhdHQgUm9sZS1QbGF5aW5nICgxODguMDYgbWlvKSB3ZWxjaGVzIGF1ZiBQbGF0eiA3IGFiZ2VydXRzY2h0IGlzdCBiZWZpbmRldCBzaWNoIGhpZXIgUmFjaW5nICgyMzguMzkpIHdlbGNoZSBkZW4gUGxhdHogdGF1c2NoZW4uIEF1Y2ggUGxhdHogNSBNaXNjICgyMTUuOTggbWlvKSB1bmQgUGxhdHogNiBQbGF0Zm9ybSAoMjAxLjYzIG1pbykgc2luZCBpbiBFdXJvcGEgdmVydGF1c2NodC4gQWxsZ2VtZWluIHNjaGVpbnQgaGllciBhdWYgZGVuIGhpbnRlcmVuIEdlbnJlcGzDpHR6ZW4gZWluZSB2ZXJzY2hpZWJ1bmcgZmVzdHN0ZWxsYmFyIHp1IHNlaW4gZGVubiBvYndvaGwgZGFzIHZlcmjDpGx0bmlzIGRlciBHZW5yZXMgZ2xlaWNoIGJsZWlidCBzaW5kIHp1c8OkdHpsaWNoIHNvd29obCBTaW11bGF0aW9uICgxMTMuMzggbWlvKSB1bmQgRmlnaHRpbmcgKDEwMS4zMiBtaW8pIGFscyBhdWNoIEFkdmVudHVyZSAoNjMuMTMgbWlvKSB1bmQgUHV6emxlICg1MC43OCBtaW8pIHZlcnRhdXNjaHQuIFZvbiBkZW4gaGludGVyZW4gUGzDpHR6ZW4gYmxlaWJ0IHNvbWl0IGVpbnppZyBTdHJhdGVneSAoNDUuMzQgbWlvKSBhdWYgc2VpbmVtIHZvcmhlcmlnZW4gbGV0enRlbiBwbGF0ei4NCg0KIyMjIyBOb3JkLUFtZXJpa2ENCmBgYHtyIHBsb3QoU2FsZXNCeUdlbnJlX05BMSksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQoNCmdyb3VwZWQgPC0gdmdzYWxlcyAgJT4lIA0KICBncm91cF9ieShHZW5yZSkgJT4lIA0KICBzdW1tYXJpemUoc3VtKE5BX1NhbGVzKSkgICU+JQ0KcmVuYW1lKA0KICAgIEdsb2JhbF9TYWxlcyA9ICJzdW0oTkFfU2FsZXMpIg0KICAgICkNCmdyb3VwZWQkR2xvYmFsX1NhbGVzPC1hc192ZWN0b3IoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpDQpvcmRlcmVkIDwtIGdyb3VwZWRbb3JkZXIoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpLCBkZWNyZWFzaW5nID0gRkFMU0VdDQoNCmF4IDwtIGxpc3QoDQogIHRpdGxlID0gIkdlbnJlIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJWZXJrw6R1ZmUgKGluIG1pbykiDQoNCikNCg0Kb3JkZXJlZCU+JQ0KICBwbG90X2x5KCkgJT4lIA0KICBhZGRfYmFycyh4PX5mY3RfcmVvcmRlcihHZW5yZSxHbG9iYWxfU2FsZXMsIC5kZXNjPSJ0cnVlIiksDQogICAgICAgICAgIHk9fkdsb2JhbF9TYWxlcywNCiAgICAgICAgICAgbmFtZT0iVmVya2F1ZnN6YWhsZW4gbmFjaCBHZW5yZSAoTkEpIg0KICAgICAgICAgICAsY29sb3JzID0gbXlQYWxldHRlKSAlPiUgDQogIGxheW91dCh0aXRsZT0iVmVya2F1ZnN6YWhsZW4gbmFjaCBHZW5yZSAoTkEpIiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5DQogICAgICAgICApDQpgYGANCkF1Y2ggaW4gTm9yZC1BbWVyaWthIGlzdCBlaW5lIFZlcnNjaGllYnVuZyBkZXIgR2VucmVzIGZlc3R6dXN0ZWxsZW4uIERpZSBUb3AgMyBzaW5kIHdlaXRlcmhpbiB2b24gQWN0aW9uICg4NzcuODMgbWlvKSwgU3BvcnRzICg2ODMuMzUgbWlvKSB1bmQgU2hvb3RlciAoNTgyLjYgbWlvKSBiZWxlZ3QuIEltIGdlZ2Vuc2F0eiB6dSBFdXJvcGEgc2luZCBoaWVyIGFsbGVyZGluZ3MgbnVyIFBsYXR6IDQgUGxhdGZvcm0gKDQ0Ny4wNSBtaW8pLCBQbGF0eiA1IE1pc2MgKDQxMC4yNCBtaW8pIHNvd2llIFBsYXR6IDYgUmFjaW5nICgzNTkuNDIpIHVuZCBQbGF0eiA3IFJvbGUtUGxheWluZyAoMzI3LjI4IG1pbykgdmVydGF1c2NodC4gUGxhdHogOCBiaXMgMTIgc2luZCB3aWUgZGllIGdsb2JhbGVuIFJlZmVyZW56d2VydGUgYW5nZW9yZG5ldCBkZXIgZWluemlnZSBVbnRlcnNjaGllZCB6d2lzY2hlIEdsb2JhbCB1bmQgTm9yZC1BbWVyaWthIGlzdCBzb21pdCBkaWUgdmVyc2NoaWVidW5nIHZvbiBSb2xlLVBsYXlpbmcgYXVmIFBsYXR6IDcuDQoNCiMjIyMgSmFwYW4NCg0KYGBge3IgcGxvdChTYWxlc0J5R2VucmVfSlAxKSwgZWNobyA9IFRSVUUsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J21hcmt1cCcsIH0NCg0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgDQogIGdyb3VwX2J5KEdlbnJlKSAlPiUgDQogIHN1bW1hcml6ZShzdW0oSlBfU2FsZXMpKSAgJT4lDQpyZW5hbWUoDQogICAgR2xvYmFsX1NhbGVzID0gInN1bShKUF9TYWxlcykiDQogICAgKQ0KZ3JvdXBlZCRHbG9iYWxfU2FsZXM8LWFzX3ZlY3Rvcihncm91cGVkJEdsb2JhbF9TYWxlcykNCm9yZGVyZWQgPC0gZ3JvdXBlZFtvcmRlcihncm91cGVkJEdsb2JhbF9TYWxlcyksIGRlY3JlYXNpbmcgPSBGQUxTRV0NCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiR2VucmUiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIlZlcmvDpHVmZSAoaW4gbWlvKSINCg0KKQ0KDQpvcmRlcmVkJT4lDQogIHBsb3RfbHkoKSAlPiUgDQogIGFkZF9iYXJzKHg9fmZjdF9yZW9yZGVyKEdlbnJlLEdsb2JhbF9TYWxlcywgLmRlc2M9InRydWUiKSwNCiAgICAgICAgICAgeT1+R2xvYmFsX1NhbGVzLA0KICAgICAgICAgICBuYW1lPSJWZXJrYXVmc3phaGxlbiBuYWNoIEdlbnJlIChKUCkiICxjb2xvcnMgPSBteVBhbGV0dGUpICU+JSANCiAgbGF5b3V0KHRpdGxlPSJWZXJrYXVmc3phaGxlbiBuYWNoIEdlbnJlIChKUCkiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgICkNCg0KYGBgDQpJbiBKYXBhbiBiZWZpbmRldCBzaWNoIFJvbGUtUGxheWluZyAoMzUyLjMxIG1pbykgbWl0IGdyb8OfZW0gQWJzdGFuZCBhdWYgUGxhdHogMSBub2NoIHZvciBkZSBzb25zdGlnZW4gUGxhdHpoaXJzY2hlbiBBY3Rpb24gKDE1OS45NSBtaW8pIHVuZCBTcG9ydHMgKDEzNS4zNyBtaW8pLiBEaWUgZWhlbWFsaWdlIHRvcCAzIFNob290ZXIgKDM4LjI4IG1pbykgZsOkbGx0IGluIEphcGFuIGF1ZiBkZW4gbGV0enRlbiBwbGF0eiBhYiB1bmQgd2lyZCB2b24gUGxhdGZvcm0gKDEzMC43NyBtaW8pIGVyc2V0enQuIE1pc2MgKDEwNy43NiBtaW8pIGthbm4gc2ljaCB3ZWl0ZXJoaW4gaW0gbWl0dGVsZmVsZCBoYWx0ZW4gd29oaW5nZWdlbiBGaWdodGluZyAoODcuMzUgbWlvKSB1bmQgU2ltdWxhdGlvbiAoNjMuNyBtaW8pIGVpbmlnZSBQbMOkdHplIGd1dCBtYWNoZW4ga8O2bm5lbiB1bmQgbnVuIGF1ZiBQbGF0eiA2IHVuZCA3IHZvcnLDvGNrZW4uIEF1Y2ggUHV6emxlIEdhbWVzICg1Ny4zMSBtaW8pIGVyZnJldWVuIHNpY2ggZWluZXIgaMO2aGVyZW4gYmVsaWVidGhlaXQgYWxzIG5vY2ggR2xvYmFsIHdvaGluZ2VnZW4gUmFjaW5nICg1Ni42OSBtaW8pIGVpbmVuIGRldXRsaWNoZW4gVmVybHVzdCBoaW5uZWhtZW4gbXVzcy4gQWR2ZW50dXJlICg1Mi4wNyBtaW8pIHVuZCBTdHJhdGVneSAoNDkuNDYgbWlvKSBibGVpYmVuIGplZG9jaCB3ZWl0ZXJoaW4gZWluZSBkZXIgVW5iZWxpZWJ0ZXN0ZW4gR2VucmVzLg0KDQojIyMgS3JlaXNkaWFncmFtbWUgey50YWJzZXR9DQoNCiMjIyMgRXVyb3BhDQpgYGB7ciBwbG90KFNhbGVzQnlHZW5yZV9FVTIpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KDQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoR2VucmUpICU+JSANCiAgc3VtbWFyaXplKHN1bShFVV9TYWxlcykpICAlPiUNCnJlbmFtZSgNCiAgICBHbG9iYWxfU2FsZXMgPSAic3VtKEVVX1NhbGVzKSINCiAgICApDQpncm91cGVkJEdsb2JhbF9TYWxlczwtYXNfdmVjdG9yKGdyb3VwZWQkR2xvYmFsX1NhbGVzKQ0Kb3JkZXJlZCA8LSBncm91cGVkW29yZGVyKGdyb3VwZWQkR2xvYmFsX1NhbGVzKSwgZGVjcmVhc2luZyA9IEZBTFNFXQ0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJHZW5yZSINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiVmVya8OkdWZlIChpbiBtaW8pIg0KDQopDQoNCg0Kb3JkZXJlZCU+JQ0KICBwbG90X2x5KCkgJT4lIA0KICBhZGRfcGllKHZhbHVlcyA9fkdsb2JhbF9TYWxlcyxsYWJlbHM9fkdlbnJlLA0KICAgICAgICAgICBuYW1lPSJWZXJrYXVmc3phaGxlbiBuYWNoIEdlbnJlIChFVSkiICxjb2xvcnMgPSBteVBhbGV0dGUpICU+JSANCiAgbGF5b3V0KHRpdGxlPSJWZXJrYXVmc3phaGxlbiBuYWNoIEdlbnJlIChFVSkiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgKQ0KYGBgDQoNCkV1cm9wYSBzaWVodCB3aWUgYmVyZWl0cyBpbiBkZXIgW1BsYXRmb3JtYW5hbHlzZV0oI1BsYXRmb3JtUmFua2luZ0J5UmVnaW9uKSBmZXN0Z2VzdGVsbHQgZGVtIEdsb2JhbGVuIEdlbnJldmVyZ2xlaWNoIHJlY2h0IMOkaG5saWNoLiBBY3Rpb24gKDIxLjYlKSBmw7xocnQgd2VpdGVyaGluIHZvciBTcG9ydHMoMTUuNSUpIHVuZCBTaG9vdGVybiAoMTIuOSUpLiBBdWYgcGxhdHogNCBpc3QgZGFubiBkZXIgZXJzdGUgVW50ZXJzY2hpZWQgZmVzdHN0ZWxsYmFyLiBBbnN0YXR0IFJvbGUtUGxheWluZyAoNy43MyUpIHdlbGNoZXMgYXVmIFBsYXR6IDcgYWJnZXJ1dHNjaHQgaXN0IGJlZmluZGV0IHNpY2ggaGllciBSYWNpbmcgKDkuNzklKSB3ZWxjaGUgZGVuIFBsYXR6IHRhdXNjaGVuLiBBdWNoIFBsYXR6IDUgTWlzYyAoOC44NyUpIHVuZCBQbGF0eiA2IFBsYXRmb3JtICg4LjI4JSkgc2luZCBpbiBFdXJvcGEgdmVydGF1c2NodC4gQWxsZ2VtZWluIHNjaGVpbnQgaGllciBhdWYgZGVuIGhpbnRlcmVuIEdlbnJlcGzDpHR6ZW4gZWluZSB2ZXJzY2hpZWJ1bmcgZmVzdHN0ZWxsYmFyIHp1IHNlaW4gZGVubiBvYndvaGwgZGFzIHZlcmjDpGx0bmlzIGRlciBHZW5yZXMgZ2xlaWNoIGJsZWlidCBzaW5kIHp1c8OkdHpsaWNoIHNvd29obCBTaW11bGF0aW9uICg0LjY2JSkgdW5kIEZpZ2h0aW5nICg0LjE2JSkgYWxzIGF1Y2ggQWR2ZW50dXJlICgyLjYzJSkgdW5kIFB1enpsZSAoMi4wOSUpIHZlcnRhdXNjaHQuIFZvbiBkZW4gaGludGVyZW4gUGzDpHR6ZW4gYmxlaWJ0IHNvbWl0IGVpbnppZyBTdHJhdGVneSAoMS44NiUpIGF1ZiBzZWluZW0gdm9yaGVyaWdlbiBsZXR6dGVuIHBsYXR6Lg0KDQoNCiMjIyMgTm9yZC1BbWVyaWthDQoNCmBgYHtyIHBsb3QoU2FsZXNCeUdlbnJlX05BMiksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQoNCmdyb3VwZWQgPC0gdmdzYWxlcyAgJT4lIA0KICBncm91cF9ieShHZW5yZSkgJT4lIA0KICBzdW1tYXJpemUoc3VtKE5BX1NhbGVzKSkgICU+JQ0KcmVuYW1lKA0KICAgIEdsb2JhbF9TYWxlcyA9ICJzdW0oTkFfU2FsZXMpIg0KICAgICkNCmdyb3VwZWQkR2xvYmFsX1NhbGVzPC1hc192ZWN0b3IoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpDQpvcmRlcmVkIDwtIGdyb3VwZWRbb3JkZXIoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpLCBkZWNyZWFzaW5nID0gRkFMU0VdDQoNCmF4IDwtIGxpc3QoDQogIHRpdGxlID0gIkdlbnJlIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJWZXJrw6R1ZmUgKGluIG1pbykiDQoNCikNCg0Kb3JkZXJlZCU+JQ0KICBwbG90X2x5KCkgJT4lIA0KICBhZGRfcGllKHZhbHVlcyA9fkdsb2JhbF9TYWxlcyxsYWJlbHM9fkdlbnJlLA0KICAgICAgICAgICBuYW1lPSJWZXJrYXVmc3phaGxlbiBuYWNoIEdlbnJlIChOQSkiLGNvbG9ycyA9IG15UGFsZXR0ZSkgJT4lIA0KICBsYXlvdXQodGl0bGU9IlZlcmthdWZzemFobGVuIG5hY2ggR2VucmUgKE5BKSIsDQogICAgICAgICB4YXhpcyA9IGF4LA0KICAgICAgICAgeWF4aXMgPSBheQ0KICAgICAgICApDQpgYGANCg0KQXVjaCBpbiBOb3JkLUFtZXJpa2EgaXN0IGVpbmUgVmVyc2NoaWVidW5nIGRlciBHZW5yZXMgZmVzdHp1c3RlbGxlbi4gRGllIFRvcCAzIHNpbmQgd2VpdGVyaGluIHZvbiBBY3Rpb24gKDIwJSksIFNwb3J0cyAoMTUuNiUpIHVuZCBTaG9vdGVyICgxMy4zJSkgYmVsZWd0LiBJbSBnZWdlbnNhdHogenUgRXVyb3BhIHNpbmQgaGllciBhbGxlcmRpbmdzIG51ciBQbGF0eiA0IFBsYXRmb3JtICgxMC4yJSksIFBsYXR6IDUgTWlzYyAoOS4zNCUpIHNvd2llIFBsYXR6IDYgUmFjaW5nICg4LjE4JSkgdW5kIFBsYXR6IDcgUm9sZS1QbGF5aW5nICg3LjQ1JSkgdmVydGF1c2NodC4gUGxhdHogOCBiaXMgMTIgc2luZCB3aWUgZGllIGdsb2JhbGVuIFJlZmVyZW56d2VydGUgYW5nZW9yZG5ldCBkZXIgZWluemlnZSBVbnRlcnNjaGllZCB6d2lzY2hlIEdsb2JhbCB1bmQgTm9yZC1BbWVyaWthIGlzdCBzb21pdCBkaWUgdmVyc2NoaWVidW5nIHZvbiBSb2xlLVBsYXlpbmcgYXVmIFBsYXR6IDcuDQoNCiMjIyMgSmFwYW4NCg0KYGBge3IgcGxvdChTYWxlc0J5R2VucmVfSlAyKSwgZWNobyA9IFRSVUUsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J21hcmt1cCcsIH0NCg0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgDQogIGdyb3VwX2J5KEdlbnJlKSAlPiUgDQogIHN1bW1hcml6ZShzdW0oSlBfU2FsZXMpKSAgJT4lDQpyZW5hbWUoDQogICAgR2xvYmFsX1NhbGVzID0gInN1bShKUF9TYWxlcykiDQogICAgKQ0KZ3JvdXBlZCRHbG9iYWxfU2FsZXM8LWFzX3ZlY3Rvcihncm91cGVkJEdsb2JhbF9TYWxlcykNCm9yZGVyZWQgPC0gZ3JvdXBlZFtvcmRlcihncm91cGVkJEdsb2JhbF9TYWxlcyksIGRlY3JlYXNpbmcgPSBGQUxTRV0NCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiR2VucmUiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIlZlcmvDpHVmZSAoaW4gbWlvKSINCg0KKQ0KDQpvcmRlcmVkJT4lDQogIHBsb3RfbHkoKSAlPiUgDQogIGFkZF9waWUodmFsdWVzID1+R2xvYmFsX1NhbGVzLGxhYmVscz1+R2VucmUsDQogICAgICAgICAgIG5hbWU9IlZlcmthdWZzemFobGVuIG5hY2ggR2VucmUgKEpQKSIgLGNvbG9ycyA9IG15UGFsZXR0ZSkgJT4lIA0KICBsYXlvdXQodGl0bGU9IlZlcmthdWZzemFobGVuIG5hY2ggR2VucmUgKEpQKSIsDQogICAgICAgICB4YXhpcyA9IGF4LA0KICAgICAgICAgeWF4aXMgPSBheQ0KICAgICAgICApDQpgYGANCg0KSW4gSmFwYW4gYmVmaW5kZXQgc2ljaCBSb2xlLVBsYXlpbmcgKDI3LjMlKSBtaXQgZ3Jvw59lbSBBYnN0YW5kIGF1ZiBQbGF0eiAxIG5vY2ggdm9yIGRlIHNvbnN0aWdlbiBQbGF0emhpcnNjaGVuIEFjdGlvbiAoMTIuNCUpIHVuZCBTcG9ydHMgKDEwLjUlKS4gRGllIGVoZW1hbGlnZSB0b3AgMyBTaG9vdGVyICgyLjk3JSkgZsOkbGx0IGluIEphcGFuIGF1ZiBkZW4gbGV0enRlbiBwbGF0eiBhYiB1bmQgd2lyZCB2b24gUGxhdGZvcm0gKDEwLjElKSBlcnNldHp0LiBNaXNjICg4LjM1JSkga2FubiBzaWNoIHdlaXRlcmhpbiBpbSBtaXR0ZWxmZWxkIGhhbHRlbiB3b2hpbmdlZ2VuIEZpZ2h0aW5nICg2Ljc3JSkgdW5kIFNpbXVsYXRpb24gKDQuOTMlKSBlaW5pZ2UgUGzDpHR6ZSBndXQgbWFjaGVuIGvDtm5uZW4gdW5kIG51biBhdWYgUGxhdHogNiB1bmQgNyB2b3Jyw7xja2VuLiBBdWNoIFB1enpsZSBHYW1lcyAoNC40NCUpIGVyZnJldWVuIHNpY2ggZWluZXIgaMO2aGVyZW4gYmVsaWVidGhlaXQgYWxzIG5vY2ggR2xvYmFsIHdvaGluZ2VnZW4gUmFjaW5nICg0LjM5JSkgZWluZW4gZGV1dGxpY2hlbiBWZXJsdXN0IGhpbm5laG1lbiBtdXNzLiBBZHZlbnR1cmUgKDQuMDMlKSB1bmQgU3RyYXRlZ3kgKDMuODMlKSBibGVpYmVuIGplZG9jaCB3ZWl0ZXJoaW4gZWluZSBkZXIgVW5iZWxpZWJ0ZXN0ZW4gR2VucmVzLg0KDQojIyB7LX0NCg0KWnUgZXJrZW5uZW4gaXN0IGhpZXIgZXJuZXV0IGRhcyBBbWVyaWthIHVuZCBFdW9wYSByZWNodCDDpGhubGljaCBpbnRlcmVzc2VuIGhhYmVuIHVuZCBudXIgYXVmIGRlbiBtaXR0bGVyZW4gdW5kIGhpbnRlcmVuIHBsw6R0emVuIHVudGVyc2NoaWVkZSBhdWZ3ZWlzZW4uIE5vcmQtQW1lcmlrYSBpc3QgYWxzIGRlciBncsO2w590ZSBNYXJrdCB3aWUgenUgZXJ3YXJ0ZW5kIGFtIG7DpGNoc3RlbiBhbiBkZW4gR2xvYmFsZW4gUmVmZXJlbnpkYXRlbiB3b2hpbmdlZ2VuIEphcGFuIGVpbiBnw6RuemxpY2ggYW5kZXJlcyBHZW5yZXNoZW1hIGVya2VubmVuIGzDpHNzdC4gSW4gSmFwYW4gZG9taW5pZXJ0IFJvbGUtUGxheWluZyB3ZWxjaGVzIHNpY2ggaW4gRXVyb3BhIHVuZCBBbWVyaWthIG51ciBhdWYgcGxhdHogNyBiZWZpbmRldCB3ZWxjaGVzIGR1cmNoIGRpZSBKYXBhbmlzY2hlIEt1bHR1ciBnZXByw6RndCBhdWNoIHNpbm4gZXJnaWJ0Lg0KDQoqKioNCg0KIyBHZW5yZWVudHdpY2tsdW5nIGltIGxhdWZlIGRlciBKYWhyZSBuYWNoIGFuemFobCB7I0dlbnJlQW1vdW50UGVyWWVhcn0NCg0KTmFjaGRlbSB3aXIgdW5zIG51biDDnGJlciBkaWUgR2VucmV2ZXJ0ZWlsdW5nIEdsb2JhbCB1bmQgaW4gZGVuIGVpbnplbG5lbiBSZWdpb25lbiBlaW4gQmlsZCBnZW1hY2h0IGhhYmVuIHfDpHJlIGVzIGludGVyZXNzYW50IGFuenVzY2hhdWVuIHdpZSBzaWNoIGRpZSBHZW5yZXMgaW0gTGF1ZmUgZGVyIEphaHJlIGVudHdpY2tlbHQgaGFiZW4gdW5kIG9iIHNpY2ggZWluIFRyZW5kIGJlaSBHZXdpc3NlbiBHZW5yZXMgZXJrZW5uZW4gbMOkc3N0LiBBbHMgZXJzdGVzIEJldHJhY2h0ZW4gd2lyIHJlaW5lIEFuemFobCBkZXIgU3BpZWxlcmVsZWFzZXMgdW5kIFtzcMOkdGVyXSgjR2VucmVTYWxlc1BlclllYXIpIGRpZSB2ZXJrYXVmc3phaGxlbi4gSGllcnp1IHZlcndlbmRlbiB3aXIgdmVyc2NoaWVkZW5lIExpbmVwbG90cyBkaWUgc2ljaCBpbiBkZXIgRGF0ZW52b3JiZXJlaXR1bmcgbmljaHQgZ3Jvw59hcnRpZyB2b24gZGVuIFtQYXJldG8tXSgjUGxhdGZvcm1hbmFseXNlKSB1bmQgW0tyZWlzZGlhZ3JhbW1lbl0oI1BsYXRmb3JtUmFua2luZ0J5UmVnaW9uKSB1bnRlcnNjaGVpZGV0LiBEaWUgdW50ZXJzY2hpZWRlIGluIGRlciBEaWFncmFtbSBlcnN0ZWxsdW5nIHdlcmRlIGljaCBqZWRvY2ggaW0gRm9sZ2VuZGVuIGF1ZnplaWdlbi4NCg0KIyMgQW56YWhsIGRlciBTcGllbGUgcHJvIEdlbnJlIHBybyBKYWhyIHsudGFic2V0fQ0KDQojIyMgTGluZXMNCg0KRGllIGVyc3RlbGx1bmcgZGVzIExpbmVzIERpYWdyYW1tZXMgaXN0IHdvaGwgZGllIHNpbXBlbHN0ZS4gV2lyIHZlcndlbmRlbiB1bnNlcmUgdm9yZ2VmaWx0ZXJ0ZXMgZGF0YS5mcmFtZSAqZmlsdGVyZWQqIHVuZCDDvGJlcmdlYmVuIGRpZXMgYW4gZGllICpwbG90X2x5KCkqIGZ1bmt0aW9uLiBEYW5hY2ggbnV0emVuIHdpciAqYWRkX2xpbmVzKiB1bSBlaW4gTGluaWVuZGlhZ3JhbW0genUgZXJzdGVsbGVuIHVuZCBzZXR6ZW4gZGllIFBhcmFtZXRlci4gRGVyIFgtV2VydCBpc3QgZGFzICpZZWFyKiwgZGVyIFktV2VydCBkaWUgKkFuemFobCouIEFscyAqY29sb3IqIHfDpGhsZW4gd2lyIGRhcyBHZW5yZSB1bmQgdW5zZXJlIEZhcmJ0YWJlbGxlIMO8YmVyZ2ViZW4gd2lyIGFuIGRpZSBmdW5rdGlvbiB2aWEgKmNvbG9ycz0qLg0KDQpgYGB7ciBwbG90KEFtb3VudE9mR2FtZXNCeUdlbnJlYnlZZWFyMSksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQoNCmdyb3VwZWQgPC0gdmdzYWxlcyAgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogIGdyb3VwX2J5KFllYXIsIEdlbnJlKSAlPiUNCiAgZHBseXI6OnN1bW1hcml6ZShBbnphaGwgPW4oKSkgJT4lIGZpbHRlcihZZWFyIT0nTi9BJyklPiVmaWx0ZXIoWWVhciE9MjAyMCkgJT4lIGZpbHRlcihZZWFyIT0nMjAxNycpICU+JQ0KICBhcy5kYXRhLmZyYW1lKCkNCg0KDQpmaWx0ZXJlZCA8LSBncm91cGVkICU+JSBzZWxlY3QoWWVhcixHZW5yZSxBbnphaGwpDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJKYWhyIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJBbnphaGwiDQoNCikNCg0KZmlsdGVyZWQgJT4lDQpwbG90X2x5KCkgJT4lIA0KICBhZGRfbGluZXMoeD1+WWVhciwNCiAgICAgICAgICAgeT1+QW56YWhsLCBjb2xvcj1+R2VucmUsY29sb3JzID0gbXlQYWxldHRlKSAlPiUgDQogbGF5b3V0KHRpdGxlPSJBbnphaGwgZGVyIFNwaWVsZXJlbGVhc2VzIHZvbiAxOTgwLTIwMTYiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgICkNCg0KYGBgDQpJbSBlcnN0ZW4gbW9tZW50IGlzdCBkaWVzZXMgRGlhZ3JhbW0gcmVjaHQgdW7DvGJlcnNpY2h0bGljaCBkb2NoIGJlaSBnZW5hdWVyZW4gQmV0cmFjaHR1bmcga2FubiBlaW4gYXVmbWVya3NhbWVyIEJldHJhY2h0ZXIgYmVyZWl0cyBlaW5pZ2UgRGluZ2UgZXJrZW5uZW4uIFp1bSBlaW5lbiBzZWhlbiB3aXIgZGFzIHp3aXNjaGVuIDE5OTMgdW5kIDIwMDMgdGF0c8OkY2hsaWNoIFNwb3J0cyBkYXMgbWVpc3QgdmVya2F1ZnRlIEdlbnJlIHdhciBiZXZvciBlcyB2b24gQWN0aW9uIGFiZ2Vsw7ZzdCB3dXJkZS4gTWlzYyBnYW1lcyBlcmZyZXV0ZW4gc2ljaCB6d2lzY2hlbiAyMDA1IHVuZCAyMDExIGdyb8OfZXIgYmVsaWVidGhlaXQgYmV2b3IgZGllc2Ugd2llZGVyIGluIGRlciBWZXJzZW5rdW5nIHZlcnNjaHdhbmRlbi4gQXVjaCBBZHZlbnR1cmUgZ2FtZXMgd2FyZW4gendpc2NoZW4gMjAwNyB1bmQgMjAxMCBhbSBiZWxpZWJ0ZXN0ZW4uDQoNCiMjIyBGaWxsZWQgTGluZXMNCg0KRGllIEVyc3RlbGx1bmcgZGVzIEZpbGxlZCBMaW5lcyBEaWFncmFtbWVzIHVudGVyc2NoZWlkZXMgc2ljaCBldHdhcyB2b24gZGVtIGVpbmZhY2ggTGluZXMtUGxvdC4gQW5zdGF0dCBkZXIgKmFkZF9MaW5lcyogZnVua3Rpb24gw7xiZXJnZWJlbiB3aXIgaGllciBkaXJla3QgZGllIFBhcmFtZXRlciBtaXQgYW4gKnBsb3RfbHkoKSouIFggaXN0IHdlaXRlcmhpbiBkYXMgSmFociwgWSBkaWUgQW56YWhsLCBkaWUgRmFyYnRhYmxldHRlICpjb2xvcnMqIHVuZCAqY29sb3I9R2VucmUqLiBEaWUgVW50ZXJzY2hpZWRlIHNpbmQgaGllciBkZXIgKnR5cGUqIHBhcmFtZXRlciB3ZWxjaGVyIGF1ZiBzY2F0dGVyIGdlc2V0eiB3aXJkLCAqbW9kZSogd2VsY2hlcyBub25lIGlzdCB1bmQgKmZpbGwqIHdlbGNoZXMgZHVyY2ggKnRvemVyb3kqIGRpZSBmw7xsbHVuZyBiaXMgenVyIHkgQWNoc2UgZXJ6ZXVndC4NCg0KYGBge3IgcGxvdChBbW91bnRPZkdhbWVzQnlHZW5yZWJ5WWVhcjIpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KDQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICBncm91cF9ieShZZWFyLCBHZW5yZSkgJT4lDQogIGRwbHlyOjpzdW1tYXJpemUoQW56YWhsID1uKCkpICU+JSBmaWx0ZXIoWWVhciE9J04vQScpJT4lZmlsdGVyKFllYXIhPTIwMjApICU+JSBmaWx0ZXIoWWVhciE9JzIwMTcnKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpDQoNCg0KZmlsdGVyZWQgPC0gZ3JvdXBlZCAlPiUgc2VsZWN0KFllYXIsR2VucmUsQW56YWhsKQ0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiSmFociINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiQW56YWhsIg0KDQopDQoNCg0KZmlsdGVyZWQgJT4lDQpwbG90X2x5KHggPSB+WWVhciwgeSA9IH5BbnphaGwsIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbm9uZScsIGZpbGwgPSAndG96ZXJveScsY29sb3IgPSB+R2VucmUgLGNvbG9ycyA9IG15UGFsZXR0ZSklPiUgDQogIGxheW91dCh0aXRsZT0iQW56YWhsIGRlciBTcGllbGVyZWxlYXNlcyB2b24gMTk4MC0yMDE2IiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5DQogICAgICAgICApDQoNCmBgYA0KDQpFaW5pZ2UgZmVpbmVyZSB1bnRlcnNjaGllZGUgTGFzc2VuIHNpY2ggaGllciBkZXV0bGljaCBiZXNzZXIgZXJrZW5uZW4gYWxzIG5vY2ggaW0gTGluZXMgRGlhZ3JhbW0uIE1hbiBlcmtlbm50IGJlaXNwaWVsc3dlaXNlIGRlbiBncm/Dn2VuIFdhY2hzdHVtIHZvbiBTdHJhdGVneSBnYW1lcyB6d2lzY2hlbiAxOTk2IHVuZCAxOTk4IGJldm9yIGRpZXNlIDIwMDAgc3RhcmsgYWJmbGFjaGVuIHVuZCBuaWNodCBtaXQgZGVtIGFsbGdlbWVpbmVuIFdhY2hzdHVtIGRlciBhbmRlcmVuIEdlbnJlcyBtaXRoYWx0ZW4ga8O2bm5lbi4gQXVjaCBkZXIgZ3Jvw59lIFdhY2hzdHVtIHZvbiBSYWNpbmcgZ2FtZXMgendpc2NoZW4gMjAwIHVuZCAyMDA0IGlzdCBndXQgZXJrZW5uYmFyLg0KDQojIyMgU3RhY2tlZCBMaW5lcyB7LmFjdGl2ZX0NCg0KRGEgc3RhY2tlZCBMaW5lcyBzZWhyIMO8YmVyc2ljaHRsaWNoIHVuZCBndXQgZGFyaW4gc2luZCBzaWNoIGVpbmVuIEdyb2JlcmVuIMO8YmVyYmxpY2sgw7xiZXIgZGllIERhdGVuIHp1IHNjaGFmZmVuIHNpbmQgZGllc2UgaGllciBhbHMgZXJzdGUgQW5zaWNodCB2b3JhdXNnZXfDpGhsdC4gVW0gZGllIGhpbnp1Z2Vow7ZyZW5kZSBUZXh0ZSBodW5kZXJ0cHJvemVudGlnIHZlcnN0ZWhlbiB6dSBrw7ZubmVuIGlzdCBlcyBhYmVyIGhpbGZyZWljaCB6dWVyc3QgZGVuIExpbmVzIHVuZCBGaWxsZWQgTGluZXMgdGFiIHp1IHN0dWRpZXJlbi4NCg0KRGllIEVyc3RlbGx1bmcgZGVzIHN0YWNrZWQgTGluZXMgRGlhZ3JhbW0gaXN0IGRlbiBGaWxsZWQgTGluZXMgc2VociDDpGhubGljaC4gRWluemlnZXIgdW50ZXJzY2hpZWQgaXN0IGRpZSBBYndlc2VuaGVpdCBkZXMgKmZpbGwqIHBhcmFtZXRlcnMgdW5kIHN0YXR0ZGVzc2VuIGRpZSB2ZXJ3ZW5kdW5nIHZvbiAqc3RhY2tncm91cD0nb25lJyogd2VsY2hlcyBkaWUgc3RhY2tlZCBMaW5lcyBlcnpldWd0Lg0KDQpgYGB7ciBwbG90KEFtb3VudE9mR2FtZXNCeUdlbnJlYnlZZWFyMyksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQoNCmdyb3VwZWQgPC0gdmdzYWxlcyAgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogIGdyb3VwX2J5KFllYXIsIEdlbnJlKSAlPiUNCiAgZHBseXI6OnN1bW1hcml6ZShBbnphaGwgPW4oKSkgJT4lIGZpbHRlcihZZWFyIT0nTi9BJyklPiVmaWx0ZXIoWWVhciE9MjAyMCkgJT4lIGZpbHRlcihZZWFyIT0nMjAxNycpICU+JQ0KICBhcy5kYXRhLmZyYW1lKCkNCg0KDQpmaWx0ZXJlZCA8LSBncm91cGVkICU+JSBzZWxlY3QoWWVhcixHZW5yZSxBbnphaGwpDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJKYWhyIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJBbnphaGwiDQoNCikNCg0KDQpmaWx0ZXJlZCAlPiUNCnBsb3RfbHkoeCA9IH5ZZWFyLCB5ID0gfkFuemFobCwgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdub25lJywgc3RhY2tncm91cCA9ICdvbmUnLGNvbG9yID0gfkdlbnJlLCBjb2xvcnMgPSBteVBhbGV0dGUpJT4lIA0KICBsYXlvdXQodGl0bGU9IkFuemFobCBkZXIgU3BpZWxlcmVsZWFzZXMgdm9uIDE5ODAtMjAxNiIsDQogICAgICAgICB4YXhpcyA9IGF4LA0KICAgICAgICAgeWF4aXMgPSBheQ0KICAgICAgICAgKQ0KDQpgYGANCg0KTGVpZGVyIHNpbmQgZGllIEZhcmJlbiBhdWZncnVuZCBlaW5lcyBGZWhsZXJzIGhpZXIgZXR3YXMgZmVobGVyaGFmdCBtZWhyIGRhenUgaW0gW0Zheml0XSgjQXVmZ2V0cmV0ZW5lUHJvYmxlbWUpIEJlaW0gQmV0cmFjaHRlbiBkZXMgU3RhY2tlZCBMaW5lIHBsb3RzIHNpbmQgamVkb2NoIHRyb3R6ZGVtIGVpbmlnZSBEaW5nZSBkaXJla3Qgc2VociBndXQgenUgZXJrZW5uZW4uIE1hbiBzaWVodCB3ZWxjaGUgR2VucmVzIGVpbiBncsO2w59lcmVzIFdhY2hzdHVtIGhpbmxlZ2VuIGFscyBhbmRlcmUuIFNvd29obCBTaG9vdGVyIGFscyBhdWNoIFB1enpsZSB1bmQgUGxhdGZvcm0gR2FtZXMgYmxlaWJlbiBpbiBkZW4gMjAxMGVyIGphaHJlbiByZWxhdGl2IGdsZWljaGJsZWliZW5kLiBBY3Rpb24sIFN0cmF0ZWd6LCBNaXNjIHVuZCBTcG9ydHMgR2FtZXMga8O2bm5lbiBqZWRvY2ggZWluIGRldXRsaWNoZXMgV2FjaHN0dW0gYXVmemVpZ2VuLg0KDQoNCiMjIyBHZW5yZXZlcnNjaGllYnVuZw0KDQpTY2hhdWVuIHdpciB1bnMgbnVuIGRpZSBFcnN0ZWxsdW5nIGRlciB6dW0gdmVyZ2xlaWNoZW4gZGVyIEdlbnJlcyB3b2hsIGludGVyZXNzYW50ZXN0ZW4gR3JhZmlrIGFuLiBEaWUgZXJzdGVsbHVuZyBpc3QgaGllciBxdWFzaSBnbGVpY2ggenUgZGVuIFN0YWNrZWQgTGluZXMuIEVpbnppZ2UgbmV1ZXJ1bmcgaXN0IGRhcyBoaW56dWbDvGdlbiBkZXMgUGFyYW1ldGVycyAqZ3JvdXBub3JtID0gJ3BlcmNlbnQnKiB3ZWxjaGVzIGRpZSBZLUFjaHNlIHZvbiBkZW0gd2VydCBkZXIgQW56YWhsIHp1IFByb3plbnR3ZXJ0ZW4gw6RuZGVydC4gQXVjaCBoaWVyIHNpbmQgamVkb2NoIGRpZSBGYXJiZW4gbGVpZGVyIFtGZWhsZXJoYWZ0XSgjQXVmZ2V0cmV0ZW5lUHJvYmxlbWUpLg0KDQpgYGB7ciBwbG90KEFtb3VudE9mR2FtZXNCeUdlbnJlYnlZZWFyNCksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQoNCmdyb3VwZWQgPC0gdmdzYWxlcyAgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogIGdyb3VwX2J5KFllYXIsIEdlbnJlKSAlPiUNCiAgZHBseXI6OnN1bW1hcml6ZShBbnphaGwgPW4oKSkgJT4lIGZpbHRlcihZZWFyIT0nTi9BJyklPiVmaWx0ZXIoWWVhciE9MjAyMCkgJT4lIGZpbHRlcihZZWFyIT0nMjAxNycpICU+JQ0KICBhcy5kYXRhLmZyYW1lKCkNCg0KDQpmaWx0ZXJlZCA8LSBncm91cGVkICU+JSBzZWxlY3QoWWVhcixHZW5yZSxBbnphaGwpDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJKYWhyIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJQcm96ZW50ICUiDQoNCikNCg0KDQpmaWx0ZXJlZCAlPiUNCnBsb3RfbHkoeCA9IH5ZZWFyLCB5ID0gfkFuemFobCwgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdub25lJywgc3RhY2tncm91cCA9ICdvbmUnLGdyb3Vwbm9ybSA9ICdwZXJjZW50Jyxjb2xvciA9IH5HZW5yZSAsY29sb3JzID0gbXlQYWxldHRlKSU+JSANCiAgbGF5b3V0KHRpdGxlPSJNYXJrZXRzaGFyZSBHZW5yZXZlcnNjaGllYnVuZyBpbiAlIHZvbiAxOTgwLTIwMTYiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgICkNCmBgYA0KDQpCZWltIEJldHJhY2h0ZW4gZsOkbGx0IGhpZXIgZGlyZWt0IGF1ZiwgZGFzcyBBY3Rpb24gR2FtZXMgMTk4MC0xOTg0IGVpbmVuIGdyb8OfZW4gTWFya3RhbnRlaWwsIHRlaWx3ZWlzZSBiaXMgaGluIHp1IDUwJSBhdXNnZW1hY2h0IGhhYmVuLiBEaWVzZSBiaXMgMTk5NCBhdWYgZ2VyYWRlbWFsIDMlIGFic2lua2VuIGJldm9yIGRlciBTdGV0aWdlIFdhY2hzdHVtIGJlZ2lubnQgYmlzIHNpZSAyMDE2IHdpZWRlciBiZWkgS25hcCA0MCUgZW5kZW4uIEF1Y2ggZGllIGdyb8OfZSBNYXJrdHByw6RzZW56IHZvbiBQbGF0Zm9ybSBTcGllbGVuIHp3aXNjaGVuIDE5ODQgdW5kIDE5OTIgaXN0IGd1dCBlcmtlbm5iYXIgd29oaW5nZWdlbiBSYWNpbmcgR2FtZXMgc2ljaCB6d2lzY2hlbiAxOTk0IHVuZCAyMDA0IGRlciBncsO2w590ZW4gYmVsaWVidGhlaXQgZXJmcmV1ZW4uDQoNCiMjIHstfQ0KDQpIaWVyYmVpIHp1IGVya2VubmVuIGlzdCBPYndvaGwgZGllIEFuemFobCBkZXIgSsOkaHJsaWNoZW4gU3BpZWxlcmVsZWFzZXMgw7xiZXIgZGllIEphaHJlIGhpbndlZyBzdGV0aWcgd8OkY2hzdCBibGVpYmVuIGRpZSBNZWlzdGVuIEdlbnJlcyDDpGhubGljaCB2aWVsIHZlcnRyZXRlbi4gQXVmZsOkbGxpZyBzaW5kIGhpZXJiZWkgU3RyYXRlZ3ktR2FtZXMgZGllIGVyc3QgMTk5MSBkYXMgZXJzdGUgbWFsIGF1ZnRyZXRlbSBTZWl0ZGVtIG9id29obCBzaWUgTGVpY2h0IGFuIE1hcmtldHNoYXJlIHZlcmxpZXJlbiBncm9iIGdsZWljaCBibGVpYmVuLiBBdcOfZXJkZW0gc2luZCBBY3Rpb24gR2FtZXMgZGllIFNwaWVsZSBtaXQgZGVyIHdvaGwgZ3LDtsOfdGVuIHZvbGF0aWxpdMOkdC4gU2luZCBlcyAxOTgyIG5vY2ggZmFzdCA1MCUgZGVyIEdhbWVyZWxlYXNlcyBmw6RsbHQgZGVyZW4gYXVma29tbWVuIDEwODQgc2Nob24gYXVmIG51ciBub2NoIGtuYXBwIDEwJSBhYiB1bmQgMTk4NiBzdGVpZ3QgZGVyIFdlcnQgd2llZGVyIGF1ZiBmYXN0IDMwJS4gRGllc2VyIFRyZW5kIHNldHp0IHNpY2ggZm9ydCBiaXMgMTk5NiBhYiB3ZWxjaGVtIFplaXRwdW5rdCBzaWNoIEFjdGlvbiBHYW1lcyB2b24gMy42JSDDvGJlciBkaWUgSmFocmUgYmlzIDIwMTYgYmlzIDM1JSBlbnR3aWNrZWxuLg0KDQoqKioNCg0KIyBHZW5yZWVudHdpY2tsdW5nIGltIGxhdWZlIGRlciBKYWhyZSBuYWNoIFZlcmthdWZzemFobGVuIHsjR2VucmVTYWxlc1BlclllYXJ9DQoNClNjaGF1ZW4gd2lyIHVucyBhbiB3aWUgc2ljaCBkaWUgdmVya8OkdWZlIGVudHdpY2tlbHQgaGFiZW4uIEhpZXJ6dSB2ZXJ3ZW5kZW4gd2lyIGRpZSBnbGVpY2hlbiBEaWFncmFtbWUgd2llIGJlcmVpdHMgYmVpIGRlciBCZXRyYWNodHVuZyBkZXIgU3BpZWxlIEFuemFobC4gRWluZSBlcmtsw6RydW5nIGRlciBlcnN0ZWxsdW5nIGRlciBEaWFncmFtbWUgZ2lidCBlcyBbaGllcl0oI0dlbnJlQW1vdW50UGVyWWVhcikuDQoNCiMjIFZlcmvDpHVmZSBwcm8gSmFociB7LnRhYnNldH0NCg0KIyMjIExpbmVzDQpgYGB7ciBwbG90KFNhbGVzQnlHZW5yZWJ5WWVhcjEpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KDQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICBncm91cF9ieShZZWFyLCBHZW5yZSkgJT4lDQogIGRwbHlyOjpzdW1tYXJpemUoZ3Jfc3VtID0gc3VtKEdsb2JhbF9TYWxlcykpICU+JSBmaWx0ZXIoWWVhciE9J04vQScpJT4lZmlsdGVyKFllYXIhPTIwMjApICU+JSBmaWx0ZXIoWWVhciE9JzIwMTcnKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpDQoNCg0KZmlsdGVyZWQgPC0gZ3JvdXBlZCAlPiUgc2VsZWN0KFllYXIsR2VucmUsZ3Jfc3VtKQ0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJKYWhyIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJWZXJrw6R1ZmUgKGluIG1pbykiDQoNCikNCg0KZmlsdGVyZWQgJT4lDQpwbG90X2x5KCkgJT4lIA0KICBhZGRfbGluZXMoeD1+WWVhciwNCiAgICAgICAgICAgeT1+Z3Jfc3VtLCBjb2xvcj1+R2VucmUgLGNvbG9ycyA9IG15UGFsZXR0ZSkgJT4lIA0KICBsYXlvdXQodGl0bGU9IlZlcmthdWZzemFobGVuIGRlciBTcGllbGVyZWxlYXNlcyB2b24gMTk4MC0yMDE2IiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5DQogICAgICAgICApDQoNCmBgYA0KDQpCZWltIGVyc3RlbiBCZXRyYWNodGVuICBmw6RsbHQgaGllciBkaXJla3QgZGllIGhvaGUgdm9sYXRpbGl0w6R0IGRlciBlaW56ZWxuZW4gR3JhcGhlbiBhdWYsIHdlbGNoZXMgZHVyY2ggZGVuIGhvaGVuIEVpbmZsdXNzIGVpbmlnZXIgZ3V0bGF1ZmVuZGVyIEdhbWVzIGF1ZiBkaWUgVmVya2F1ZnN6YWhsZW4genVyw7xja3p1ZsO8aHJlbiBpc3QuIEFtIGVpbmZhY2hzdGVuIGlzdCBkaWVzIHp3aXNjaGVuIDE5ODAgdW5kIDE5OTIgZXJrZW5uYmFyLiAxOTgxIGlzdCBlaW4gc3Bpa2UgaW4gQWN0aW9uIEdhbWVzIGVya2VubmJhciwgbmFtZXRsaWNoIGR1cmNoIGRpZSB2ZXLDtmZmZW50bGljaHVuZyBuYW1lbnRsaWNoZXIgc3BpZWxlIHdpZSBGcm9nZ2VyIHVuZCBQaXRmYWxsLiBJbSBKYWhyIDE5ODQgZXJrZW5uYmFyIGlzdCBkYW5uIGRlciBzcGlrZSB2b24gU2hvb3Rlcm4gZHVyY2ggRHVjay1HYW1lIHNvd2llIFBsYXRmb3JtIGdhbWVzIGluIDE5ODUgZHVyY2ggU3VwZXIgTWFyaW8gQnJvcy4gU3VwZXIgTWFyaW8gcHLDpGd0IGRpZSBIaXN0b3JpZSBkZXIgUGxhdGZvcm0gR2FtZXMgYXVjaCB6d2lzY2hlbiAxOTg4IHVuZCAxOTkwIG1pdCBTdXBlciBNYXJpbyBCcm9zIDMgdW5kIFN1cGVyIE1hcmlvIFdvcmxkLiBEYXMgU3BpZWwgd2VsY2hlcyAxOTg5IGVpbmVuIGF1c3NjaGxhZyBkZXIgUHV6emxlLUdhbWVzIHZlcnVyc2FjaHQgZMO8cmZ0ZSBzb2dhciBMZXNlcm4sIHdlbGNoZSBuaWNodCBUZWlsIGRlciBHYW1pbmctQ29tbXVuaXR5IHNpbmQgZWluIGJlZ3JpZmYgc2VpbjogVGV0cmlzLg0KDQojIyMgRmlsbGVkIExpbmVzDQoNCmBgYHtyIHBsb3QoU2FsZXNCeUdlbnJlYnlZZWFyMiksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQoNCmdyb3VwZWQgPC0gdmdzYWxlcyAgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogIGdyb3VwX2J5KFllYXIsIEdlbnJlKSAlPiUNCiAgZHBseXI6OnN1bW1hcml6ZShncl9zdW0gPSBzdW0oR2xvYmFsX1NhbGVzKSkgJT4lIGZpbHRlcihZZWFyIT0nTi9BJyklPiVmaWx0ZXIoWWVhciE9MjAyMCkgJT4lIGZpbHRlcihZZWFyIT0nMjAxNycpICU+JQ0KICBhcy5kYXRhLmZyYW1lKCkNCg0KDQpmaWx0ZXJlZCA8LSBncm91cGVkICU+JSBzZWxlY3QoWWVhcixHZW5yZSxncl9zdW0pDQoNCmF4IDwtIGxpc3QoDQogIHRpdGxlID0gIkphaHIiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIlZlcmvDpHVmZSAoaW4gbWlvKSINCg0KKQ0KDQoNCmZpbHRlcmVkICU+JQ0KcGxvdF9seSh4ID0gflllYXIsIHkgPSB+Z3Jfc3VtLCB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ25vbmUnLCBmaWxsID0gJ3RvemVyb3knLGNvbG9yID0gfkdlbnJlICxjb2xvcnMgPSBteVBhbGV0dGUpICU+JSANCiAgbGF5b3V0KHRpdGxlPSJWZXJrYXVmc3phaGxlbiBkZXIgU3BpZWxlcmVsZWFzZXMgdm9uIDE5ODAtMjAxNiIsDQogICAgICAgICB4YXhpcyA9IGF4LA0KICAgICAgICAgeWF4aXMgPSBheQ0KICAgICAgICAgKQ0KDQpgYGANCg0KRHVyY2ggQmV0cmFjaHRlbiBkZXMgRmlsbGVkIExpbmUgUGxvdHMgZXJrZW5uZW4gd2lyIGd1dCBkZW4gSG9jaCBkZXIgU3RyYXRlZ2llc3BpZWxlIGltIEphaHIgMTk5OSBkdXJjaCBzcGllbGUgd2llIFBva2Vtb24gU3RhZGl1bSwgV2Fyem9uZSAyMTAwIG9kZXIgQWdlIG9mIEVtcGlyZXMgSUkuIEF1Y2ggZGllIFNwaWtlcyBkZXIgUm9sZS1QbGF5aW5nIEdhbWVzIGltIGdsZWljaGVuIEphaHIgZHVyY2ggUG9rZW1vbiBHb2xkL1NpbGJlciB1bmQgRmluYWwgRmFudGFzeSBWSUlJIHNvd2llIDE5OTYgZHVyY2ggUG9rZW1vbiBSb3QvQmxhdSBzaW5kIGRldXRsaWNoIGVya2VubmJhci4NCg0KIyMjIFN0YWNrZWQgTGluZXMgey5hY3RpdmV9DQoNCmBgYHtyIHBsb3QoU2FsZXNCeUdlbnJlYnlZZWFyMyksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQoNCmdyb3VwZWQgPC0gdmdzYWxlcyAgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogIGdyb3VwX2J5KFllYXIsIEdlbnJlKSAlPiUNCiAgZHBseXI6OnN1bW1hcml6ZShncl9zdW0gPSBzdW0oR2xvYmFsX1NhbGVzKSkgJT4lIGZpbHRlcihZZWFyIT0nTi9BJyklPiVmaWx0ZXIoWWVhciE9MjAyMCkgJT4lIGZpbHRlcihZZWFyIT0nMjAxNycpICU+JQ0KICBhcy5kYXRhLmZyYW1lKCkNCg0KDQpmaWx0ZXJlZCA8LSBncm91cGVkICU+JSBzZWxlY3QoWWVhcixHZW5yZSxncl9zdW0pDQoNCmF4IDwtIGxpc3QoDQogIHRpdGxlID0gIkphaHIiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIlZlcmvDpHVmZSAoaW4gbWlvKSINCg0KKQ0KDQoNCmZpbHRlcmVkICU+JQ0KcGxvdF9seSh4ID0gflllYXIsIHkgPSB+Z3Jfc3VtLCB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ25vbmUnLCBzdGFja2dyb3VwID0gJ29uZScsY29sb3IgPSB+R2VucmUgLGNvbG9ycyA9IG15UGFsZXR0ZSklPiUgDQogIGxheW91dCh0aXRsZT0iVmVya2F1ZnN6YWhsZW4gZGVyIFNwaWVsZXJlbGVhc2VzIHZvbiAxOTgwLTIwMTYiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgICkNCmBgYA0KDQpTdGFja2VkIExpbmVzIHNpbmQgdmVybXV0bGljaCBkYXMgQmVzdGUgRGlhZ3JhbW0gdW0gVmVya2F1ZnN6YWhsZW4gbWl0IGRlciBBbnphaGwgenUgdmVyZ2xlaWNoZW4uIEFtIGF1ZmbDpGxsaWdzdGVuIGhpZXIgc2luZCwgZGFzcyBkaWUgVm9sYXRpbGl0w6R0IGluIGRlbiBmcsO8aGVyZW4gSmFocmVuICgxOTgwLTE5OTUpIGJlaSBnZXJpbmdlcmVyIHByw6RzZW56IHZvbiBWaWRlb3NwaWVsZW4gZGV1dGxpY2ggZ3LDtsOfZXIgYXVzZsOkbGx0IGFscyBpbiBkZXIgYW56YWhsIGRlciBWaWRlb3NwaWVsZS4gSW4gZGVuIFNww6R0ZXJlbiBKYWhyZW4gdm9yYWxsZW0gYWIgMjAwMyBmYWxsZW4gZGllIFNjaHdhbmt1bmdlbiBoaWVyIGplZG9jaCBkZXV0bGljaCBnZXJpbmdlciBhdXMsIHdhcyB2ZXJtdXRsaWNoIGFuIGRlciBow7ZoZXJlbiBNYXNzZSB2b24gVmlkZW9zcGllbGVuIHVuZCBkYW1pdCBlaW5lbSBicmVpdCBnZWbDpGNoZXJ0ZXJlbSBOdXR6ZXJpbnRlcmVzc2UgbGllZ3QuDQoNCiMjIyBHZW5yZXZlcnNjaGllYnVuZw0KDQpgYGB7ciBwbG90KFNhbGVzQnlHZW5yZWJ5WWVhcjQpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KDQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICBncm91cF9ieShZZWFyLCBHZW5yZSkgJT4lDQogIGRwbHlyOjpzdW1tYXJpemUoZ3Jfc3VtID0gc3VtKEdsb2JhbF9TYWxlcykpICU+JSBmaWx0ZXIoWWVhciE9J04vQScpJT4lZmlsdGVyKFllYXIhPTIwMjApICU+JSBmaWx0ZXIoWWVhciE9JzIwMTcnKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpDQoNCg0KZmlsdGVyZWQgPC0gZ3JvdXBlZCAlPiUgc2VsZWN0KFllYXIsR2VucmUsZ3Jfc3VtKQ0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJKYWhyIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJQcm96ZW50ICUiDQoNCikNCg0KDQpmaWx0ZXJlZCAlPiUNCnBsb3RfbHkoeCA9IH5ZZWFyLCB5ID0gfmdyX3N1bSwgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdub25lJywgc3RhY2tncm91cCA9ICdvbmUnLGdyb3Vwbm9ybSA9ICdwZXJjZW50Jyxjb2xvciA9IH5HZW5yZSAsY29sb3JzID0gbXlQYWxldHRlKSU+JSANCiAgbGF5b3V0KHRpdGxlPSJNYXJrZXRzaGFyZSBHZW5yZXZlcnNjaGllYnVuZyBpbiAlIHZvbiAxOTgwLTIwMTYiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgICkNCmBgYA0KDQpEdXJjaCBkaWUgaG9oZSBWb2xhdGlsaXTDpHQgaXN0IGRpZSBHcmFmaWsgaW4gZGVuIGZyw7xoZXJlbiBKYWhyZW4gdm9yYWxsZW0gendpc2NoZW4gMTk4MCB1bmQgMTk5MiBzZWhyIGR1cmNoZWluYW5kZXJuIHVuZCBUZWlsd2Vpc2UgcmVjaHQgc2Nod2llcmlnIHp1IGxlc2VuLiBJbiBkZW4gZGFyYXVmIGZvbGdlbmRlbiBKYWhyZW4gaXN0IGVzIGFiZXIgZGV1dGxpY2ggbGVpY2h0ZXIgYmVzdGltbXRlIGRpbmdlIHdpZSBkYXMgZXJzdG1hbGlnZSBhdWZ0cmV0ZW5zIGRlciBTdHJhdGVnaWVzcGllbGUgMTk5MiBvZGVyIGRpZSBmYXN0IFZvbGxzdMOkbmRpZ2UgQWJzdGluZW56IHZvbiBQdXp6bGUgR2FtZXMgendpc2NoZW4gMTk5NSB1bmQgMjAwMiBzb3dpZSBhYiAyMDEyIHp1IGVya2VubmVuLg0KDQojIyB7LX0NCg0KV2llIHp1IGVyd2FydGVuIGzDpHNzdCBzaWNoIGhpZXIgZWluIEdyb8OfZXIgb3ZlcmxhcCB6dSBkZW4gQW56YWhsIGRlciBHYW1lcmVsZWFzZXMgZmVzdHN0ZWxsZW4gZXMga2FubiBqZWRvY2ggZWluZSBIb2hlIFZvbGl0aWxpdMOkdCBkdXJjaCBlaW56ZWxuZSBTcGllbGVyZWxlYXNlcyB2b3JhbGxlbSBpbiBmcsO8aGVyZW4gSmFocmVuIGZlc3RnZXN0ZWxsdCB3ZXJkZW4uIERpZXMgaGF0IGRlbiBHcnVuZCBkYXMgZWluaWdlICJLYXNzZW5zY2hsYWdlciIgaGllciBlaW5lbiBncm/Dn3RlaWwgZGVzIE1hcmt0ZXMgYXVzbWFjaGVuIHVuZCBpaG4gc29taXQgc3RhcmsgYmVlaW5mbHVzc2VuLiBBbnp1bWVya3RlbiBpc3QgamVkb2NoIGRhcyBTcGllbGUgZ2VybmUgUmVyZWxlYXN0IHdlcmRlbiB2b3JhbGxlbSBhdWYgdW50ZXJzY2hpZWRsaWNoZW4gS29uc29sZW4sIGRpZXMgaW4gdW5zZXJlbSBEYXRlbnNhdHogamVkb2NoIG5pY2h0IHp1c2FtbWVnZWbDvGhydCB3aXJkLiBXZWl0ZXJlcyBoaWVyenUgaW0gW0Zheml0XSgjQXVmZ2V0cmV0ZW5lUHJvYmxlbWUpDQoNCioqKg0KDQojIEdlbnJlZW50d2lja2x1bmcgaW0gbGF1ZmUgZGVyIEphaHJlIG5hY2ggVmVya2F1ZnN6YWhsZW4gcHJvIFNwaWVsIHsjR2VucmVTYWxlc1BlckdhbWVQZXJZZWFyfQ0KDQpOYWNoZGVtIHdpciBudW4gQW5hbHlzaWVydCBoYWJlbiB3aWUgc2ljaCBkaWUgQW56YWhsIGRlciBTcGllbGVyZWxlYXNlcyBzb3dpZSBkaWUgVmVya2F1ZnN6YWhsZW4gZW50d2lja2VsdCBoYWJlbiB3w6RyZSBlcyBkb2NoIGludGVyZXNzYW50IGJlaWRlcyBnZWdlbsO8YmVyenVzdGVsbGVuIHVuZCBkaXJla3QgenUgdmVyZ2xlaWNoZW4uIEhpZXJ6dSB2ZXJ3ZW5kZW4gd2lyIGVybmV1dCBkaWUgYmVyZWl0cyBiZWthbm50ZW4gW0RpYWdyYW1tZV0oI0dlbnJlQW1vdW50UGVyWWVhcikgbnV0emVuIGplZG9jaCBpbiBkZXIgKmRwbHlyOjpzdW1tYXJpemUoKSogZnVua3Rpb24gZGllIFN1bW1lIGRlciBWZXJrYXVmc3phaGxlbiB3ZWxjaGUgd2lyIGR1cmNoIGRpZSBBbnphaGwgZGVyIEVpbnRyw6RnZSB0ZWlsZW4uDQoNCiMjIFZlcmvDpHVmZSBwcm8gU3BpZWwgcHJvIEphaHIgey50YWJzZXR9DQoNCiMjIyBMaW5lcw0KYGBge3IgcGxvdChTYWxlc1BlckdhbWVQZXJHZW5yZWJ5WWVhcjEpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KDQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICBncm91cF9ieShZZWFyLCBHZW5yZSkgJT4lDQogIGRwbHlyOjpzdW1tYXJpemUoZ3Jfc3VtID0gc3VtKEdsb2JhbF9TYWxlcykvbigpKSAlPiUgZmlsdGVyKFllYXIhPSdOL0EnKSU+JWZpbHRlcihZZWFyIT0yMDIwKSAlPiUgZmlsdGVyKFllYXIhPScyMDE3JykgJT4lDQogIGFzLmRhdGEuZnJhbWUoKQ0KDQoNCmZpbHRlcmVkIDwtIGdyb3VwZWQgJT4lIHNlbGVjdChZZWFyLEdlbnJlLGdyX3N1bSkNCmF4IDwtIGxpc3QoDQogIHRpdGxlID0gIkphaHIiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIlZlcmvDpHVmZSBwcm8gU3BpZWwiDQoNCikNCg0KZmlsdGVyZWQgJT4lDQpwbG90X2x5KCkgJT4lIA0KICBhZGRfbGluZXMoeD1+WWVhciwNCiAgICAgICAgICAgeT1+Z3Jfc3VtLCBjb2xvcj1+R2VucmUgLGNvbG9ycyA9IG15UGFsZXR0ZSkgJT4lIA0KICBsYXlvdXQodGl0bGU9IlZlcmvDpHVmZSBwcm8gU3BpZWwgbmFjaCBHZW5yZSB2b24gMTk4MC0yMDE2IiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5DQogICAgICAgICApDQoNCmBgYA0KDQpJbSBMaW5lcy1QbG90IGVya2VubmVuIHdpciBkaXJla3QgZGllIGluIGRlciBbVmVya2F1ZnN6YWhsYW5hbHlzXSgjR2VucmVTYWxlc1BlclllYXIpIGdlbmFubnRlbiBFeHRyZW1lIHdlbGNoZSBkdXJjaCBlaW56ZWxuZSBTcGllbGUsIHZvcmFsbGVtIGluIGRlbiBmcsO8aGVyZW4gSmFocmVuLCBiZWVpbmZsdXNzdCB3ZXJkZW4uIEFtIGRldXRsaWNoc3RlbiBpc3QgZGllcyBpbiBTaG9vdGVyIEdhbWVzIDE5ODQgZHVyY2ggRHVjay1HYW1lIHVuZCBQbGF0Zm9ybSBzcGllbGUgMTk4NSBkdXJjaCBTdXBlciBNYXJpbyBCcm9zLiBBdWNoIFRldHJpcyAoUHV6emxlIDE5ODkpIHNvd2llIFN1cGVyIE1hcmlvIEJyb3MgMyAoUGxhdGZvcm0gMTk4OCkgdW5kIFN1cGVyIE1hcmlvIFdvcmxkIChQbGF0Zm9ybSAxOTkwKSBzaW5kIGRldXRsaWNoIGVya2VubmJhci4gTmV1IGVya2VubmJhciBpc3QgaGllciBkZXIgQXVzc2NobGFnIGluIFJhY2luZyBnYW1lcyAxOTkyIGR1cmNoIGRlbiBLbGFzc2lrZXIgU3VwZXIgTWFyaW8gS2FydCB3ZXNzZW4gTmFjaGZvbGdlciBiaXMgaGV1dGUgYXVmIGZhc3QgamVkZXIgTmludGVuZG8gS29uc29sZSB2ZXLDtmZmZW50bGljaHQgd3VyZGVuLg0KDQojIyMgRmlsbGVkIExpbmVzIHsuYWN0aXZlfQ0KDQpJbiBkZW0gRmFsbCBkZXIgVmVya8OkdWZlIFBybyBKYWhyIHNpbmQgZGllIFN0YWNrZWQgTGluZXMgbGVpZGVyIHdlbmlnIGF1c3NjaGxhZ2dlYmVuZCB1bmQgZGFoZXIgYXVjaCBuaWNodCBhbHMgZXJzdGUgYW5zaWNodCB2b3JhdXNnZXfDpGhsdC4gWnVtIHZlcnN0ZWhlbiBkZXIgQW5hbHlzZSBzb2xsdGUgamVkb2NoIGRlciBMaW5lcy1UYWIgenVlcnN0IGdlbGVzZW4gd2VyZGVuLg0KDQpgYGB7ciBwbG90KFNhbGVzUGVyR2FtZVBlckdlbnJlYnlZZWFyMiksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQoNCmdyb3VwZWQgPC0gdmdzYWxlcyAgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogIGdyb3VwX2J5KFllYXIsIEdlbnJlKSAlPiUNCiAgZHBseXI6OnN1bW1hcml6ZShncl9zdW0gPSBzdW0oR2xvYmFsX1NhbGVzKS9uKCkpICU+JSBmaWx0ZXIoWWVhciE9J04vQScpJT4lZmlsdGVyKFllYXIhPTIwMjApICU+JSBmaWx0ZXIoWWVhciE9JzIwMTcnKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpDQoNCg0KZmlsdGVyZWQgPC0gZ3JvdXBlZCAlPiUgc2VsZWN0KFllYXIsR2VucmUsZ3Jfc3VtKQ0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiSmFociINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiVmVya8OkdWZlIHBybyBTcGllbCINCg0KKQ0KDQpmaWx0ZXJlZCAlPiUNCnBsb3RfbHkoeCA9IH5ZZWFyLCB5ID0gfmdyX3N1bSwgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdub25lJywgZmlsbCA9ICd0b3plcm95Jyxjb2xvciA9IH5HZW5yZSAsY29sb3JzID0gbXlQYWxldHRlKSAlPiUgDQogIGxheW91dCh0aXRsZT0iVmVya8OkdWZlIHBybyBTcGllbCBuYWNoIEdlbnJlIHZvbiAxOTgwLTIwMTYiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgICkNCg0KYGBgDQoNCkJlaW0gQmV0cmFjaHRlbiBkZXIgRmlsbGVkLUxpbmVzIGbDpGxsdCBhdWYgZGFzIG5lYmVuIGRlbiBCZXJlaXRzIGdlbmFubnRlbiBFeHRyZW1lbiBSYWNpbmcgZ2FtZXMgYXVjaCBpbSBKYWhyZSAxOTkwIHNjaG9uIGVpbmVuIEhvY2hwdW5rdCBkdXJjaCBGLTEgUmFjZSBlcmZ1aHIuIEF1Y2ggZGFzIEV4dHJlbSBkZXMgQWN0aW9uIGdlbnJlcyAxOTg3IGR1cmNoIFplbGRhIElJOiBUaGUgQWR2ZW50dXJlIG9mIExpbmsgaXN0IGhpZXIgZGV1dGxpY2hlciBlcmtlbm5iYXIuDQoNCiMjIyBTdGFja2VkIExpbmVzIA0KDQpgYGB7ciBwbG90KFNhbGVzUGVyR2FtZVBlckdlbnJlYnlZZWFyMyksZWNobyA9IFRSVUUsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J21hcmt1cCcsIH0NCg0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgZ3JvdXBfYnkoWWVhciwgR2VucmUpICU+JQ0KICBkcGx5cjo6c3VtbWFyaXplKGdyX3N1bSA9IHN1bShHbG9iYWxfU2FsZXMpL24oKSkgJT4lIGZpbHRlcihZZWFyIT0nTi9BJyklPiVmaWx0ZXIoWWVhciE9MjAyMCkgJT4lIGZpbHRlcihZZWFyIT0nMjAxNycpICU+JQ0KICBhcy5kYXRhLmZyYW1lKCkNCg0KDQpmaWx0ZXJlZCA8LSBncm91cGVkICU+JSBzZWxlY3QoWWVhcixHZW5yZSxncl9zdW0pDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJKYWhyIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJWZXJrw6R1ZmUgcHJvIFNwaWVsIg0KDQopDQoNCmZpbHRlcmVkICU+JQ0KcGxvdF9seSh4ID0gflllYXIsIHkgPSB+Z3Jfc3VtLCB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ25vbmUnLCBzdGFja2dyb3VwID0gJ29uZScsY29sb3IgPSB+R2VucmUsIGNvbG9ycyA9IG15UGFsZXR0ZSklPiUgDQogIGxheW91dCh0aXRsZT0iVmVya8OkdWZlIHBybyBTcGllbCBuYWNoIEdlbnJlIHZvbiAxOTgwLTIwMTYiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgICkNCmBgYA0KDQpTdGFja2VkIExpbmVzIGlzdCBoaWVyIGbDvHIgZWluZSBBbmFseXNlIGRlciBlaW56ZWxuZW4gU3BpZWxlZ2VucmVzIGxlaWRlciBuaWNodCBoaWxmcmVpY2guIERlciBhdWZtZXJrc2FtZSBCZW9iYWNodGVyIHdpcmQgc2ljaCBqZWRvY2ggYW4gZWluZSBkZXIgZXJzdGVuIEdyYWZpa2VuIGVyaW5uZXJuIGluIGRlbmVuIHdpciBbZGllIFNhbGVzIHBybyBHYW1lXSgjVmlkZW9HYW1lUmVsZWFzZXMpIGFuYWx5c2llcnQgaGFiZW4gdW5kIHNpY2ggRnJhZ2VuIHdhcnVtIGRpZSBXZXJ0ZSBoaWVyIGRldXRsaWNoIGjDtmhlciBhdXNmYWxsZW4gYWxzIG5vY2ggYmV2b3IuIFdhciBpbiBkZXIgQW5hbHlzZSBvaG5lIEdlbnJlcyBkZXIgTWF4aW1hbHdlcnQgbm9jaCBiZWkgNCBzbyBpc3QgZXIgSGllciBiZWkgbWVociBhbHMgMjAuIERpZXMgbGllZ3Qgdm9yYWxsZW0gZGFyYW4sIGRhc3MgQWN0aW9uIGdhbWVzIGluIGRlbiBGcsO8aGVyZW4gSmFocmVuIGVpbmVuIGdyb8OfdGVpbCBkZXIgUmVsZWFzZXMgYXVzbWFjaGVuIGJlaSBkZW4gdmVya2F1ZnN6YWhsZW4gYWJlciBlaGVyIGdlcmluZyBhdXNmYWxsZW4gdW5kIGRlbiBkdXJjaHNjaG5pdHQgZGFoZXIgaGVydW50ZXJ6aWVoZW4uIFNpbmQgZGllIFNwaWVsZSBuYWNoIEdlbnJlIGF1ZmdldGVpbHQgYmVlaW5mbHVzc3QgZGFzIHNjaGxlY2h0IHBlcmZvcm1lbmRlIEFjdGlvbiBHZW5yZSBkaWUgVmVya2F1ZnN6YWhsZW4gcHJvIFNwaWVsIGRlciBhbmRlcmVuIGplZG9jaCBuaWNodCB1bmQgc28gZXJoYWx0ZW4gd2lyIGFkZGl0aXYgZWluZSBkZXV0bGljaCBncsO2w59lcmUgWmFobCBhbHMgenV2b3IuDQoNCiMjIyBHZW5yZXZlcnNjaGllYnVuZyANCg0KYGBge3IgcGxvdChTYWxlc1BlckdhbWVQZXJHZW5yZWJ5WWVhcjQpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KDQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICBncm91cF9ieShZZWFyLCBHZW5yZSkgJT4lDQogIGRwbHlyOjpzdW1tYXJpemUoZ3Jfc3VtID0gc3VtKEdsb2JhbF9TYWxlcykvbigpKSAlPiUgZmlsdGVyKFllYXIhPSdOL0EnKSU+JWZpbHRlcihZZWFyIT0yMDIwKSAlPiUgZmlsdGVyKFllYXIhPScyMDE3JykgJT4lDQogIGFzLmRhdGEuZnJhbWUoKQ0KDQoNCmZpbHRlcmVkIDwtIGdyb3VwZWQgJT4lIHNlbGVjdChZZWFyLEdlbnJlLGdyX3N1bSkNCmF4IDwtIGxpc3QoDQogIHRpdGxlID0gIkphaHIiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIlByb3plbnQgJSINCg0KKQ0KZmlsdGVyZWQgJT4lDQpwbG90X2x5KHggPSB+WWVhciwgeSA9IH5ncl9zdW0sIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbm9uZScsIHN0YWNrZ3JvdXAgPSAnb25lJyxncm91cG5vcm0gPSAncGVyY2VudCcsY29sb3IgPSB+R2VucmUsIGNvbG9ycyA9IG15UGFsZXR0ZSklPiUgDQogIGxheW91dCh0aXRsZT0iTWFya2V0c2hhcmUgaW4gVmVya8OkdWZlIHBybyBTcGllbCBuYWNoIEdlbnJlIHZvbiAxOTgwLTIwMTYiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXkNCiAgICAgICAgICkNCmBgYA0KDQpEdXJjaCBkaWUgaG9oZSB2b2xhdGlsaXTDpHQgaW4gZGVuIEZyw7xoZXJlbiBKYWhyZW4gaXN0IGF1Y2ggaGllciB3aWUgYmVpIGRlbiBWZXJrYXVmc3phaGxlbiBkYXMgR2VucmVzaGlmdCBEaWFncmFtbSB3ZW5pZyBhdXNzY2hsYWdnZWJlbmQuIEFCIDE5OTQga2FubiBtYW4gamVkb2NoIGRldXRsaWNoIGVya2VubmVuIHdpciBzaWNoIGRpZSBHZW5yZXMgaW0gbGF1ZmUgZGVyIEphaHJlIGVudHdpY2tlbG4uIFNob290ZXIgd2VyZGVuIGRldXRsaWNoIGJlbGllYnRlciB3b2hpbmdlZ2VibiBSb2xlLVBsYXlpbmcgZ2FtZXMgYXVmIGRlbSBhYnN0ZWlnZW5kZW4gQXN0IHNpbmQuDQoNCiMjIHstfQ0KDQpBdWNoIGhpZXIgaXN0IHdpZSBlcndhcnRldCBkaWUgRW50d2lja2x1bmcgUHJvemVudHVhbCDDpGhubGljaC4gQXVmZsOkbGxpZyBpc3QgamVkb2NoIGRhcyBTaG9vdGVyIHRyb3R6IGlocmVyIGdlcmluZ2VuIFZlcnRyZXR1bmcgaW4gZGVyIFByb3plbnR1YWxlbiBWZXJ0ZWlsdW5nIDE5ODQgc293aWUgMjAxNCwyMDE1IHVuZCAyMDE2IGRpZSBOYXNlIFZvcm5lIGhhYmVuLiBQbGF0Zm9ybSBHYW1lcyBoYWJlbiAxOTg1LDE5ODggdW5kIDE5OTAgZGllIE5hc2UgVm9ybmUuIERpZSBIb2NoemVpdCBkZXIgUHV6emxlIEdhbWVzIHNpbmQgdW5hbmdlZm9jaHRlbiAxOTg4IG1pdCBkZW0gV2VsdHdlaXRiZWthbm50ZW4gdW5kIGF1ZiBQbGF0eiA2IGRlciBtZWlzdHZlcmthdWZ0ZW4gdmlkZW9zcGllbGU6IFRldHJpcy4gQXVmZsOkbGxpZyBzaW5kIHZvcmFsbGVtIGRpZSBNb2Rlcm5lcmVuIGVudHdpY2tsdW5nZW4uIFNpbmQgaW4gZGVuIDE5OTYtMjAwNWVyIEphaHJlbiBSb2xlLVBsYXlpbmcgdW5kIHNvbWl0IGxhbmdzYW1lIGltbWVyc2l2ZSBlcmxlYm5pc3NlIG5vY2ggZGV1dGxpY2ggQmVsaWVidGVyIGhhYmVuIGhldXR6dXRhZ2UgU2hvb3RlciBtaXQgaWhyZW0gUnVuZGVuYmFzaWVydGVtLCAiRmFzdCBQYWNlZCIgYWxzbyBzY2huZWxsZW0gc3BpZWxmbHVzcyBkaWUgTmFzZSBWb3JuZS4gSW4gZGVyIE1vZGVybmVuIFdlbHQgaXN0IGVzIGRldXRsaWNoIGVpbmZhY2hlciB1bmQgZsO8ciBWaWVsZSBsZXV0ZSB3ZW5pZ2VyIFplaXRpbnRlbnNpdiBrdXJ6IGVpbmUgUnVuZGUgdm9uIDE1LTQ1IG1pbnV0ZW4genUgc3BpZWxlbiBhbHMgc2ljaCBTdHVuZGVubGFuZyBpbiBlaW5lIFJvbGxlIGhpbmVpbnp1dmVyc2V0emVuLiBWaWVsZW4gTWVuc2NoZW4gZmVobHQgZWluZmFjaCBaZWl0IG9kZXIgR2VkdWxkIHVtIHNpY2ggaW4gZGVyIFplaXQgdm9uIG1vZGVybmVuIE1lZGllbiB3aWUgVGlrLVRvayBvZGVyIEluc3RhZ3JhbW0sIHdlbGNoZSBzaWNoIGF1ZiBrdXJ6ZSBlcmxlYm5pc3NlIHZvbiBvZnQgd2VuaWdlbiBTZWt1bmRlbiBzcGV6aWFsaXNpZXJ0IGhhYmVuLCBpbiBlaW4gSW1tZXJzaXZlcyBlcmxlYm5pcyBoZXJlaW56dXZlcnNldHplbi4NCg0KKioqDQoNCiMgR2VucmV2ZXJ0ZWlsdW5nIG5hY2ggUHVibGlzaGVyIHsjR2VucmVCeVB1Ymxpc2hlckdsb2JhbH0gIA0KDQpEYSB3aXIgbnVuIHNvd29obCBHZW5yZXMgYWxzIGF1Y2ggUHVibGlzaGVyIGJldHJhY2h0ZXQgaGFiZW4gd8OkcmUgZXMgZG9jaCBkZXIgZWluemlnIGxvZ2lzY2hlIHNjaHJpdHQgZGllc2UgYmVpZGVuIERhdGVuIHp1c2FtbWVuenVmw7xocmVuIHVuZCB6dSB2ZXJnbGVpY2hlbi4gR2lidCBlcyBoaWVyIFB1Ymxpc2hlciBkaWUgdmVyc2NoaWVkZW5lIEdlbnJlcyBiZXZvcnp1Z2VuIGJ6dy4gZGVyZW4gQmVzdHNlbGxlciBzaWNoIGluIGJlc3RpbW10ZW4gR2VucmVzIFR1bW1lbG4/DQoNCkhpZXJ6dSB2ZXJ3ZW5kZW4gd2lyIGVpbiBzdGFja2VkIEJhci1QbG90LiBEZXIgYmVnaW5uIGRlciBEaWFncmFtbWVyc3RlbGx1bmcgaXN0IGhpZXJiZWkgw6RobmxpY2ggd2llIG5vY2ggYmVpIFtQYXJldG9kaWFncmFtbWVuXSgjUGxhdGZvcm1hbmFseXNlKS4gUmVsYXRpdiBzY2huZWxsIGbDpGxsdCBoaWVyIGplZG9jaCBhdWYgZGFzIHdpciBhbnN0YXR0IG51ciBlaW5lcyBEYXRhZnJhbWVzIFp3ZWkgUHJvZHV6aWVyZW4uIFp1bSBlaW5lbiBkZXIgYmVyZWl0cyBiZWthbm50ZSAqZ3JvdXBlZCogRGF0YWZyYW1lIHdlbGNoZXIgUHVibGlzaGVyLCBHZW5yZSB1bmQgVmVya2F1ZnN6YWhsZW4gZWJlbmplbmVyIEdlbnJlcyBiZWluaGFsdGV0LiBadW0gYW5kZXJlbiAqUHVibGlzaGVyU2FsZXMqIHdlbGNoZXIgZWluZSBMaXN0ZSBkZXIgUHVibGlzaGVyIG1pdCBHZXNhbXR2ZXJrYXVmc3phaGxlbiB2b24gbWVociBhbHMgMzAwIG1pbyBlbnRow6RsdC4gRGllc2VuIHZlcndlbmRlbiB3aXIgaW0gd2VpdGVyZW4gdmVybGF1ZiB1bSBhdXMgdW5zZXJlbSAqZ3JvdXBlZCogRGF0ZW5zYXR6IGFsbGUgUHVibGlzaGVyIHp1IGVudGZlcm5lbiBkaWUgc2ljaCBuaWNodCBpbiAqUHVibGlzaGVyU2FsZXMqIGJlZmluZGVuLiBEYXMgZ2VzY2hpZWh0IG1pdCBoaWxmZSBkZXMgKmZpbHRlcigpKiBjb21tYW5kcyB1bmQgZGVtIFNjaGxhZ3dvcnQgKiVpbiUqLiBEZXIgcmVzdCBkZXIgRGlhZ3JhbW1lcnN0ZWxsdW5nIHZlcmjDpGx0IHNpY2ggZXF1aXZhbGVudCB6dXIgW1B1Ymxpc2hlcmFuYWx5c2VdKCNQdWJsaXNoZXJSZWxlYXNlcykgbWl0IGRlbSB1bnRlcnNjaGllZCBkYXMgZGllIEJhcnMgYmVpIGRlciBEaWFncmFtbWVyc3RlbGx1bmcgbmljaHQgc29ydGllcnQgd2VyZGVuLg0KDQoNCiMjIEdlbnJldmVydGVpbHVuZyBwcm8gUHVibGlzaGVyIHsudGFic2V0fQ0KDQojIyMgVmVya8OkdWZlDQoNCmBgYHtyIHBsb3QoU2FsZXNHZW5yZWJ5UHVibGlzaGVyKSwgZWNobyA9IFRSVUUsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J21hcmt1cCcsIH0NCg0KDQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoUHVibGlzaGVyLEdlbnJlKSAlPiUgDQogIHN1bW1hcml6ZShzdW0oR2xvYmFsX1NhbGVzKSkgICU+JQ0KcmVuYW1lKA0KICAgIEdsb2JhbF9TYWxlcyA9ICJzdW0oR2xvYmFsX1NhbGVzKSINCiAgICApIA0KDQpQdWJsaXNoZXJTYWxlcyA8LSBncm91cGVkICU+JSANCiAgZ3JvdXBfYnkoUHVibGlzaGVyKSAlPiUgDQogIHN1bW1hcml6ZShzdW0oR2xvYmFsX1NhbGVzKSkgJT4lDQpyZW5hbWUoDQogICAgR2xvYmFsX1NhbGVzID0gInN1bShHbG9iYWxfU2FsZXMpIg0KICAgICkgJT4lIGZpbHRlcihHbG9iYWxfU2FsZXM+MzAwKQ0KDQpncm91cGVkIDwtIGdyb3VwZWQgJT4lIGZpbHRlcihQdWJsaXNoZXIgJWluJSBQdWJsaXNoZXJTYWxlcyRQdWJsaXNoZXIpDQoNCmdyb3VwZWQkR2xvYmFsX1NhbGVzPC1hc192ZWN0b3IoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpDQoNCmdyb3VwZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwoZ3JvdXBlZCRQdWJsaXNoZXIsICJFbnRlcnRhaW5tZW50IikNCmdyb3VwZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwoZ3JvdXBlZCRQdWJsaXNoZXIsICJJbnRlcmFjdGl2ZSIpDQpncm91cGVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKGdyb3VwZWQkUHVibGlzaGVyLCAiU3R1ZGlvcyIpDQpncm91cGVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKGdyb3VwZWQkUHVibGlzaGVyLCAiR2FtZXMiKQ0KZ3JvdXBlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChncm91cGVkJFB1Ymxpc2hlciwgIkdhbWUiKQ0KDQogIA0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJHZW5yZSINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiVmVya8OkdWZlIChpbiBtaW8pIg0KDQopDQoNCmdyb3VwZWQlPiUNCiAgcGxvdF9seSh4PX5QdWJsaXNoZXIsDQogICAgICAgICAgIHk9fkdsb2JhbF9TYWxlcywNCiAgICAgICAgICAgIHR5cGU9J2JhcicsDQogICAgICAgICAgIGNvbG9yPX5HZW5yZSwgY29sb3JzID0gbXlQYWxldHRlKSAgJT4lIA0KICBsYXlvdXQodGl0bGU9IlZlcmvDpHVmZSBwcm8gR2VucmUgcHJvIFB1Ymxpc2hlciIsDQogICAgICAgICB4YXhpcyA9IGF4LA0KICAgICAgICAgeWF4aXMgPSBheSwNCiAgICAgICAgIGJhcm1vZGUgPSAnc3RhY2snDQogICAgICAgICApDQoNCg0KYGBgDQoNCkJlaW0gQmV0cmFjaHRlbiBkZXIgVmVya2F1ZnN6YWhsZW4gZsOkbGx0IGRpcmVrdCBhdWYsIGRhc3MgZGllIG1laXN0ZW4gUHVibGlzaGVyIGJlc3RpbW10ZSBHZW5yZXMgcHLDpGZlcmllcmVuLiBBY3RpdmlzaW9uIGhhYmVuIG1pdCBDYWxsIG9mIER1dHkgZWluZW4gZ3Jvw590ZWlsIGlocmVyIHZlcmvDpHVmZSBpbSBTaG9vdGVyIEdlbnJlLiBEYXMgRWxlY3Ryb25pYyBBcnRzIG1pdCBGSUZBIHVuZCBNYWRkZW5ORkwgaW0gU3BvcnQgR2VucmUgYnJlaXQgdmVydHJldGVuIHNpbmQgaXN0IHdlbmlnIFZlcnd1bmRlcmxpY2guIFNob290ZXJuIChCYXR0bGVmaWVsZCkgdW5kIFJhY2luZyAoTmVlZCBmb3IgU3BlZWQpIHNpbmQgamVkb2NoIGF1Y2ggc2VociBCZWxpZWJ0ZSBHZW5yZXMgYmVpIGRlbSBVUy1iYXNpZXJ0ZW0gR2FtaW5nIHJpZXNlbi4gTmludGVuZG8gc3BlemlmaXppZXJ0IHNpY2ggd2VuaWcgVmVyd3VuZGVybGljaCBhdWYgUGxhdGZvcm0gKFN1cGVyIE1hcmlvKSB1bmQgUm9sZS1QbGF5aW5nKFBva2Vtb24pLiBTb255IGhpbmdlZ2VuIGbDpGNoZXJuIGlociBhbmdlYm90IHJlbGF0aXYgYnJlaXQgdW5kIGhhYmVuIG5lYmVuIDExMC41NyBtaW8gaW4gUmFjaW5nIGF1Y2ggMTA0IG1pbyBpbiBQbGF0Zm9ybSwgODAgbWlvIGluIE1pc2MgdW5kIDk0LjUgbWlvIGluIEFjdGlvbi4gVGFrZS1Ud28gbWl0IEdyYW5kIFRoZWZ0IEF1dG8gdW5kIFJlYWQgZGVhZCBSZWRlbXB0aW9uIHNwZXppZmllcmVuIHNpY2ggd2VuaWcgdmVyd3VuZGVybGljaCBhdWYgQWN0aW9uIHdvaGluZ2VnZW4gc2ljaCBUSFEgd2llZGVyIHJlbGF0aXYgYnJlaXQgZsOkY2hlcnQuIFp1IGd1dGVyIGxldHp0IGbDpGhydCBVYmlzb2Z0IGVpbmUgendlaWdldGVpbHRlIFNjaG5pZW5lIG1pdCBBY3Rpb24gKEFzc2Fzc2luJ3MgQ3JlZWQpIHVuZCBNaXNjIChKdXN0IERhbmNlKS4NCg0KIyMjIEFuemFobA0KDQpgYGB7ciBwbG90KEFtb3VudEdlbnJlYnlQdWJsaXNoZXIpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KDQoNCg0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgDQogIGdyb3VwX2J5KFB1Ymxpc2hlcixHZW5yZSkgJT4lIA0KICBzdW1tYXJpemUoQW56YWhsID1uKCksc3VtKEdsb2JhbF9TYWxlcykpICAlPiUNCnJlbmFtZSgNCiAgICBHbG9iYWxfU2FsZXMgPSAic3VtKEdsb2JhbF9TYWxlcykiDQogICAgKQ0KDQpQdWJsaXNoZXJTYWxlcyA8LSBncm91cGVkICU+JSANCiAgZ3JvdXBfYnkoUHVibGlzaGVyKSAlPiUgDQogIHN1bW1hcml6ZShzdW0oR2xvYmFsX1NhbGVzKSkgJT4lDQpyZW5hbWUoDQogICAgR2xvYmFsX1NhbGVzID0gInN1bShHbG9iYWxfU2FsZXMpIg0KICAgICkgJT4lIGZpbHRlcihHbG9iYWxfU2FsZXM+MzAwKQ0KDQoNCg0KZ3JvdXBlZCA8LSBncm91cGVkICAlPiUgZmlsdGVyKFB1Ymxpc2hlciAlaW4lIFB1Ymxpc2hlclNhbGVzJFB1Ymxpc2hlcikNCg0KZ3JvdXBlZCRHbG9iYWxfU2FsZXM8LWFzX3ZlY3Rvcihncm91cGVkJEdsb2JhbF9TYWxlcykNCmdyb3VwZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwoZ3JvdXBlZCRQdWJsaXNoZXIsICJFbnRlcnRhaW5tZW50IikNCmdyb3VwZWQkUHVibGlzaGVyIDwtc3RyX3JlbW92ZV9hbGwoZ3JvdXBlZCRQdWJsaXNoZXIsICJJbnRlcmFjdGl2ZSIpDQpncm91cGVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKGdyb3VwZWQkUHVibGlzaGVyLCAiU3R1ZGlvcyIpDQpncm91cGVkJFB1Ymxpc2hlciA8LXN0cl9yZW1vdmVfYWxsKGdyb3VwZWQkUHVibGlzaGVyLCAiR2FtZXMiKQ0KZ3JvdXBlZCRQdWJsaXNoZXIgPC1zdHJfcmVtb3ZlX2FsbChncm91cGVkJFB1Ymxpc2hlciwgIkdhbWUiKQ0KDQoNCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiR2VucmUiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIkFuemFobCINCg0KKQ0KDQpncm91cGVkJT4lDQogIHBsb3RfbHkoeD1+UHVibGlzaGVyLA0KICAgICAgICAgICB5PX5BbnphaGwsDQogICAgICAgICAgICB0eXBlPSdiYXInLA0KICAgICAgICAgICBjb2xvcj1+R2VucmUgLGNvbG9ycyA9IG15UGFsZXR0ZSkgICU+JSANCiAgbGF5b3V0KHRpdGxlPSJBbnphaGwgcHJvIEdlbnJlIHBybyBQdWJsaXNoZXIiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXksDQogICAgICAgICBiYXJtb2RlID0gJ3N0YWNrJw0KICAgICAgICAgKQ0KDQoNCg0KYGBgDQoNCkJldHJhY2h0ZW4gd2lyIGRpZSBBbnphaGwgZGVyIFNwaWVsZSB1bmQgc3RlbGwgZGllc2UgZGVuIFZlcmthdWZzemFobGVuIGdlZ2Vuw7xiZXIgZsOkbGx0IGhpZXIgdm9yYWxsZW0gYXVmLCBkYXNzIEZpcm1lbiBtaXQgRm9jdXMgaW4gZGVuIFZlcmthdWZzemFobGVuIGRpZXNlIGluIGRlciBQcm9kdWt0aW9uIG5vY2ggbWVociBQcmlvcml0aXNpZXJlbi4gSW50ZXJlc3NhbnQgaXN0IGF1Y2gsIGRhcyBBY3Rpdmlzb24gcHJvZHVrdGlvbnNmb2N1cyBkZXV0bGljaCBtZWhyIGF1ZiBhY3Rpb24gR2FtZXMgbGllZ3QgYWxzIGF1ZiBTaG9vdGVybiBkaWVzZSBzaWNoIGltIHZlcmdsZWljaCBqZWRvY2ggZGV1dGxpY2ggc2NobGVjaHRlciB2ZXJrYXVmZW4uDQoNCiMjIHstfQ0KDQpCZWkgZGVtIHZlcmdsZWljaCBkZXIgV2VydGUgaXN0IGhpZXIgenUgYmVtZXJrZW4sIGRhc3MgZGllIG1laXN0ZW4gUHVibGlzaGVyIEhpZXJiZWkgc2ljaCBtaXQgZGVyIEFuemFobCBkZXIgU3BpZWxlIHVuZCBkZW4gU2FsZXMgZ3V0IGFiZGVja2VuLiBEaWUgYXVmZsOkbGxpZ3N0ZW4gZGlza3JlcGFuemVuIHNpbmQgaGllcmJlaSBFQSBtaXQgZGVtIFNwb3J0cyBHZW5yZSB1bmQgaWhyZW4gasOkcmxpY2ggcmVsZWFzdGVuIFNwaWVsZW4gRmlGYS9OQkEyayBldGMuIHNvd2llIE5pbnRlbmRvIG1pdCBkZXIgUGxhdGZvcm1yZWloZSBTdXBlciBNYXJpby4gDQoNCioqKg0KDQoNCiMgR2VucmV2ZXJ0ZWlsdW5nIGbDvHIgUHVibGlzaGVyIEVsZWN0cm9uaWMgQXJ0c3sjR2VucmVCeVB1Ymxpc2hlckVBfSANCg0KU2NoYXVlbiB3aXIgdW5zIGRpZXNlIEJlaWRlbiBGaXJtZW4gbm9jaCBlaW5tYWwgaW0gRGV0YWlsIGFuLiBIaWVyenUgdmVyd2VuZGVuIHdpciBlcm5ldXQgW1BhcmV0by1dKCNQbGF0Zm9ybWFuYWx5c2UpIHVuZCBbS3JlaXNkaWFncmFtbV0oI1BsYXRmb3JtUmFua2luZ0J5UmVnaW9uKSBkaWUgdW5zIGJlcmVpdHMgYXVzIHZvcmRlcmVuIFRlaWxlbiBkZXIgQXVzYXJiZWl0dW5nIGJla2FubnQgc2luZC4NCg0KIyMgR2VucmUgZsO8ciBFbGVjdHJvbmljIEFydHMgey50YWJzZXR9DQoNCiMjIyBCYWxrZW5kaWFncmFtbWUgey50YWJzZXR9DQoNCiMjIyMgVmVya2F1ZnN6YWhsZW4gDQoNCmBgYHtyIHBsb3QoR2VucmVieVB1Ymxpc2hlckVBMSksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQoNCg0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgDQogIGdyb3VwX2J5KFB1Ymxpc2hlcixHZW5yZSkgJT4lIA0KICBzdW1tYXJpemUoc3VtKEdsb2JhbF9TYWxlcykpICAlPiUNCnJlbmFtZSgNCiAgICBHbG9iYWxfU2FsZXMgPSAic3VtKEdsb2JhbF9TYWxlcykiDQogICAgKSAlPiUgDQogIGZpbHRlcihQdWJsaXNoZXIgPT0gIkVsZWN0cm9uaWMgQXJ0cyIpDQoNCg0KZ3JvdXBlZCRHbG9iYWxfU2FsZXM8LWFzX3ZlY3Rvcihncm91cGVkJEdsb2JhbF9TYWxlcykNCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiR2VucmUiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIlZlcmvDpHVmZSAoaW4gbWlvKSINCg0KKQ0KDQpncm91cGVkJT4lDQogIHBsb3RfbHkoKSAlPiUgYWRkX2JhcnMoeD1+R2VucmUsDQogICAgICAgICAgIHk9fkdsb2JhbF9TYWxlcywNCiAgICAgICAgICAgY29sb3I9fkdlbnJlICxjb2xvcnMgPSBteVBhbGV0dGUpICAlPiUgDQogIGxheW91dCh0aXRsZT0iVmVya2F1ZnN6YWhsZW4gZsO8ciBFbGVjdHJvbmljIEFydHMiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXksDQogICAgICAgICBiYXJtb2RlID0gJ3N0YWNrJywNCiAgICAgICAgIHNob3dsZWdlbmQgPSBGQUxTRQ0KICAgICAgICAgKQ0KDQpgYGANCg0KQmVpbSBCZXRyYWNodGVuIGRlciBTYWxlcyBlcmtlbm5lbiB3aXIgZGFzIHdpZSBiZXJlaXRzIHZvcmhlciBmZXN0Z2VzdGVsbHQgU3BvcnRzICg0NzkuNjcgbWlvKSBhbiBlcnN0ZXIgU3RlbGxlIHN0ZWh0LiBNaXQgZGV1dGxpY2hlbSBBYnN0YW5kIGRhbmFjaCBmb2xnZW4gU2hvb3RlciAoMTU4LjI2IG1pbyksIFJhY2luZyAoMTQ1Ljc3IG1pbykgdW5kIEFjdGlvbiAoMTE1LjU0IG1pbykuIERhcyBlaW56aWcgYW5kZXJlIFJlbGV2YW50ZSBHZW5yZSBpc3QgU2ltdWxhdGlvbiBtaXQgODkuNTMgbWlvIGluIFNhbGVzLiBSb2xlLVBsYXlpbmcgKDM1LjMgbWlvKSwgRmlnaHRpbmcgKDMxLjM5IG1pbyksIE1pc2MgKDI0Ljk1IG1pbykgc293aWUgU3RyYXRlZ3kgKDE0LjA4IG1pbyksIFBsYXRmb3JtICg2LjUzIG1pbyksIEFkdmVudHVyZSAoNC43NSBtaW8pIHVuZCBQdXp6bGUgKDQuNTUgbWlvKSBzcGllbGVuIGVpbmUgZWhlciB1bnRlcmdlb3JkbmV0ZSBSb2xsZS4NCg0KIyMjIyBBbnphaGwNCg0KYGBge3IgcGxvdChBbW91bnRHZW5yZWJ5UHVibGlzaGVyRUExKSwgZWNobyA9IFRSVUUsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J21hcmt1cCcsIH0NCg0KZ3JvdXBlZCA8LSB2Z3NhbGVzICAlPiUgDQogIGdyb3VwX2J5KFB1Ymxpc2hlcixHZW5yZSkgJT4lIA0KICBzdW1tYXJpemUoQW56YWhsID1uKCkpICAlPiUgDQogIGZpbHRlcihQdWJsaXNoZXIgPT0gIkVsZWN0cm9uaWMgQXJ0cyIpDQoNCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiR2VucmUiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIkFuemFobCINCg0KKQ0KDQoNCmdyb3VwZWQlPiUNCiAgcGxvdF9seSgpICU+JSBhZGRfYmFycyh4PX5HZW5yZSwNCiAgICAgICAgICAgeT1+QW56YWhsLA0KICAgICAgICAgICBjb2xvcj1+R2VucmUgLGNvbG9ycyA9IG15UGFsZXR0ZSkgICU+JSANCiAgbGF5b3V0KHRpdGxlPSJBbnphaGwgZGVyIFNwaWVsZXJlbGVhc2VzIG5hY2ggR2VucmUgZsO8ciBFbGVjdHJvbmljIEFydHMgIiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5LA0KICAgICAgICAgYmFybW9kZSA9ICdzdGFjaycsDQogICAgICAgICBzaG93bGVnZW5kID0gRkFMU0UNCiAgICAgICAgICkNCg0KYGBgDQoNCkluIGRlciBEZXRhaWxsYW5zaWNodCBzZWhlbiBBbnphaGwgZGVyIFNwaWVsZSB1bmQgU2FsZXMgZGV1dGxpY2ggZ2VyaW5nZXIgYXVzLiBEZW4gZXJzdGVuIFBsYXR6IGJlbGVndCB3ZWl0ZXJoaW4gU3BvcnRzICg1NjEpIHZvciBBY3Rpb24gKDE4MyksIFJhY2luZyAoMTU5KSwgU2hvb3RlciAoMTM5KSB1bmQgU2ltdWxhdGlvbiAoMTE2KS4gQXVjaCBkaWUgZWhlciBpcmVsZXZhbnRlbiBHZW5yZXMgd2llIE1pc2MgKDQ2KSwgRmlnaHRpbmcgKDM5KSB1bmQgU3RyYXRlZ3kgKDM3KSBzaW5kIHdlaXRlcmhpbiBrYXVtIHZlcnRyZXRlbi4NCg0KIyMjIEtyZWlzZGlhZ3JhbW1lIHsudGFic2V0fQ0KDQojIyMjIFZlcmthdWZzemFobGVuIA0KDQpgYGB7ciBwbG90KEdlbnJlYnlQdWJsaXNoZXJFQTIpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KDQoNCmdyb3VwZWQgPC0gdmdzYWxlcyAgJT4lIA0KICBncm91cF9ieShQdWJsaXNoZXIsR2VucmUpICU+JSANCiAgc3VtbWFyaXplKHN1bShHbG9iYWxfU2FsZXMpKSAgJT4lDQpyZW5hbWUoDQogICAgR2xvYmFsX1NhbGVzID0gInN1bShHbG9iYWxfU2FsZXMpIg0KICAgICkgJT4lIA0KICBmaWx0ZXIoUHVibGlzaGVyID09ICJFbGVjdHJvbmljIEFydHMiKQ0KDQoNCmdyb3VwZWQkR2xvYmFsX1NhbGVzPC1hc192ZWN0b3IoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpDQoNCmF4IDwtIGxpc3QoDQogIHRpdGxlID0gIkdlbnJlIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJWZXJrw6R1ZmUgKGluIG1pbykiDQoNCikNCg0KZ3JvdXBlZCU+JQ0KICBwbG90X2x5KCkgJT4lIA0KICBhZGRfcGllKHZhbHVlcyA9fkdsb2JhbF9TYWxlcyxsYWJlbHM9fkdlbnJlLHRleHRpbmZvPSdsYWJlbCtwZXJjZW50Jywgcm90YXRpb24gPSAxMTAsIHNvcnQgPSBGQUxTRSwNCiAgICAgICAgICAgbmFtZT0iVmVya2F1ZnN6YWhsZW4gcHJvIEdlbnJlIGbDvHIgRWxlY3Ryb25pYyBBcnRzIiAsY29sb3JzID0gbXlQYWxldHRlKSAlPiUgDQogIGxheW91dCh0aXRsZT0iVmVya2F1ZnN6YWhsZW4gcHJvIEdlbnJlIGbDvHIgRWxlY3Ryb25pYyBBcnRzIiwNCiAgICAgICAgIHhheGlzID0gYXgsDQogICAgICAgICB5YXhpcyA9IGF5LA0KICAgICAgICAgc2hvd2xlZ2VuZCA9IEZBTFNFLA0KICAgICAgICAgYXV0b3NpemUgPSBGDQogICAgICAgICApDQoNCg0KYGBgDQoNCkJlaW0gQmV0cmFjaHRlbiBkZXIgU2FsZXMgZXJrZW5uZW4gd2lyIGRhcyB3aWUgYmVyZWl0cyB2b3JoZXIgZmVzdGdlc3RlbGx0IFNwb3J0cyAoNDMuMiUpIGFuIGVyc3RlciBTdGVsbGUgc3RlaHQuIE1pdCBkZXV0bGljaGVtIEFic3RhbmQgZGFuYWNoIGZvbGdlbiBTaG9vdGVyICgxNC4zJSksIFJhY2luZyAoMTMuMSUpIHVuZCBBY3Rpb24gKDEwLjQlKS4gRGFzIGVpbnppZyBhbmRlcmUgUmVsZXZhbnRlIEdlbnJlIGlzdCBTaW11bGF0aW9uIG1pdCA4LjA2JSBkZXIgU2FsZXMuIFJvbGUtUGxheWluZyAoMy4xOCUpLCBGaWdodGluZyAoMi44MyUpLCBNaXNjICgyLjI1JSkgc293aWUgU3RyYXRlZ3kgKDEuMjclKSwgUGxhdGZvcm0gKDAuNTg4JSksIEFkdmVudHVyZSAoMC40MjglKSB1bmQgUHV6emxlICgwLjQxJSkgc3BpZWxlbiBlaW5lIGVoZXIgdW50ZXJnZW9yZG5ldGUgUm9sbGUuDQoNCiMjIyMgQW1uemFobA0KDQpgYGB7ciBwbG90KEFtb3VudEdlbnJlYnlQdWJsaXNoZXJFQTIpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KDQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoUHVibGlzaGVyLEdlbnJlKSAlPiUgDQogIHN1bW1hcml6ZShBbnphaGwgPW4oKSkgICU+JSANCiAgZmlsdGVyKFB1Ymxpc2hlciA9PSAiRWxlY3Ryb25pYyBBcnRzIikNCg0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJHZW5yZSINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiQW56YWhsIg0KDQopDQoNCmdyb3VwZWQlPiUNCiAgcGxvdF9seSgpICU+JSANCiAgYWRkX3BpZSh2YWx1ZXMgPX5BbnphaGwsbGFiZWxzPX5HZW5yZSx0ZXh0aW5mbz0nbGFiZWwrcGVyY2VudCcsc29ydCA9IFRSVUUsIHJvdGF0aW9uID0gOTAsDQogICAgICAgICAgIG5hbWU9IkFuemFobCBkZXIgU3BpZWxlcmVsZWFzZXMgcHJvIEdlbnJlIGbDvHIgRWxlY3Ryb25pYyBBcnRzIiAsY29sb3JzID0gbXlQYWxldHRlKSAlPiUgDQogIGxheW91dCh0aXRsZT0iQW56YWhsIGRlciBTcGllbGVyZWxlYXNlcyBwcm8gR2VucmUgZsO8ciBFbGVjdHJvbmljIEFydHMiLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXksDQogICAgICAgICBzaG93bGVnZW5kID0gRkFMU0UsDQogICAgICAgICBhdXRvc2l6ZSA9IEYNCiAgICAgICAgICkNCg0KYGBgDQoNCkluIGRlciBEZXRhaWxsYW5zaWNodCBzZWhlbiBBbnphaGwgZGVyIFNwaWVsZSB1bmQgU2FsZXMgZGV1dGxpY2ggZ2VyaW5nZXIgYXVzLiBEZW4gZXJzdGVuIFBsYXR6IGJlbGVndCB3ZWl0ZXJoaW4gU3BvcnRzICg0MS41JSkgdm9yIEFjdGlvbiAoMTMuNSUpLCBSYWNpbmcgKDExLjglKSwgU2hvb3RlciAoMTAuMyUpIHVuZCBTaW11bGF0aW9uICg4LjU5JSkuIEF1Y2ggZGllIGVoZXIgaXJlbGV2YW50ZW4gR2VucmVzIHdpZSBNaXNjICgzLjQlKSwgRmlnaHRpbmcgKDIuODklKSB1bmQgU3RyYXRlZ3kgKDIuNzQlKSBzaW5kIHdlaXRlcmhpbiBrYXVtIHZlcnRyZXRlbi4NCg0KIyMgey19DQoNClNjaGF1ZW4gd2lyIHVucyBFQSBoaWVyIGltIERldGFpbCBhbiBmw6RsbHQgYXVmIGRhcyBkaWUgRGlza3JlcGFueiB6d2lzY2hlbiBTYWxlcyB1bmQgQW56YWhsIGRlciBHYW1lcmVsZWFzZXMgZsO8ciBFQSBiZWkgU3BvcnRzIGdhciBuaWNodCBzbyBncm/DnyBpc3QgKDQxLjUlIHZzIDQzLjIlKSB3aWUgdm9yaGVyIGdlZGFjaHQuIERpZSBncsO2w59lcmVuIGRpc2tyZXBhbnplbiBzaW5kIGhpZXIgU2hvb3RlciB3ZWxjaGVzIG51ciAxMCUgZGVyIEdhbWVyZWxlYXNlcyBzaW5kIGFiZXIgZ3V0IDE1JSBkZXIgU2FsZXMgdW5kIEFjdGlvbiBtaXQgMTMuNSUgZGVyIEdhbWVyZWxlYXNlcyB1bmQgMTAuNCUgZGVyIFNhbGVzLg0KDQojIEdlbnJldmVydGVpbHVuZyBmw7xyIE5pbnRlbmRvIHsjR2VucmVCeVB1Ymxpc2hlck5pbnRlbmRvfSANCg0KTmFjaGRlbSB3aXIgbnVuIGhlcmF1c2dlZnVuZGVuIGhhYmVuIGRhcyBiZWkgRWxlY3Ryb25pYyBBcnRzIGRpZSBEaXNrcmVwYW56IHp3aXNjaGVuIFNhbGVzIHVuZCBBbnphaGwgZGVyIFNwaWVsZSBnYXIgbmljaHQgc28gZ3Jvw58gaXN0IHdpZSB2b3JoZXIgZ2VkYWNodCBiZXRyYWNodGVuIHdpciBudW4gZGllIGdsZWljaGVuIERhdGVuIGbDvHIgTmludGVuZG8uIERpZSBGcmFnZSBkaWUgc2ljaCBoaWVyIHN0ZWxsdCBpc3Qgb2IgYmVpIE5pbnRlbmRvIGVpbiDDpGhubGljaGVyIHZlcmxhdWYgZmVzdHN0ZWxsYmFyIGlzdCBvZGVyIG9iIHNpY2ggYmVpIGRpZXNlbiBiZXN0aW1tdGUgR2VucmVzIGVpbmZhY2ggZGV1dGxpY2ggYmVzc2VyIHZlcmthdWZlbiBhbHMgc2llIHNvbGx0ZW4uDQoNCioqKg0KDQojIyBHZW5yZXZlcnRlaWx1bmcgZsO8ciBOaW50ZW5kbyB7LnRhYnNldH0NCg0KIyMjIEJhbGtlbmRpYWdyYW1tZSB7LnRhYnNldH0NCg0KIyMjIyBWZXJrYXVmc3phaGxlbg0KDQpgYGB7ciBwbG90KEdlbnJlYnlQdWJsaXNoZXJOaW50ZW5kbzEpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KDQoNCmdyb3VwZWQgPC0gdmdzYWxlcyAgJT4lIA0KICBncm91cF9ieShQdWJsaXNoZXIsR2VucmUpICU+JSANCiAgc3VtbWFyaXplKHN1bShHbG9iYWxfU2FsZXMpKSAgJT4lDQpyZW5hbWUoDQogICAgR2xvYmFsX1NhbGVzID0gInN1bShHbG9iYWxfU2FsZXMpIg0KICAgICkgJT4lIA0KICBmaWx0ZXIoUHVibGlzaGVyID09ICJOaW50ZW5kbyIpDQoNCg0KZ3JvdXBlZCRHbG9iYWxfU2FsZXM8LWFzX3ZlY3Rvcihncm91cGVkJEdsb2JhbF9TYWxlcykNCg0KYXggPC0gbGlzdCgNCiAgdGl0bGUgPSAiR2VucmUiDQopDQoNCmF5IDwtIGxpc3QoDQogIHRpdGxlID0gIlZlcmvDpHVmZSAoaW4gbWlvKSINCg0KKQ0KDQpncm91cGVkJT4lDQogIHBsb3RfbHkoKSAlPiUgYWRkX2JhcnMoeD1+R2VucmUsDQogICAgICAgICAgIHk9fkdsb2JhbF9TYWxlcywNCiAgICAgICAgICAgY29sb3I9fkdlbnJlICxjb2xvcnMgPSBteVBhbGV0dGUpICAlPiUgDQogIGxheW91dCh0aXRsZT0iVmVya2F1ZnN6YWhsZW4gcHJvIEdlbnJlIGbDvHIgTmludGVuZG8iLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXksDQogICAgICAgICBiYXJtb2RlID0gJ3N0YWNrJywNCiAgICAgICAgIHNob3dsZWdlbmQgPSBGQUxTRQ0KICAgICAgICAgKQ0KDQoNCmBgYA0KDQpXaWUgYmVyZWl0cyBpbiBkZXIgW0dlbnJlYW5hbHlzZSBkZXIgUHVibGlzaGVyXSgjR2VucmVCeVB1Ymxpc2hlckdsb2JhbCkgZmVzdGdlc3RlbGx0IHZlcmthdWZlbiBzaWNoIFBsYXRmb3JtLVNwaWVsZSAoNDI3LjIxIG1pbykgZsO8ciBOaW50ZW5kbyBhbSBiZXN0ZW4uIERvY2ggYXVjaCBSb2xlLVBsYXlpbmcgKDI4NC45IG1pbyksIFNwb3J0cyAoMjE4IG1pbykgdW5kIE1pc2MgKDE4MC42NyBtaW8pIG1hY2hlbiBrZWluZW4gdW53ZXNlbnRsaWNoZW4gVGVpbCBpaHJlciBWZXJrw6R1ZmUgYXVzLiBTZWxic3QgZGllIHdlbmlnZXIgUHJvbWluZW50ZW4gR2VucmVzIHdpZSBSYWNpbmcgKDE1MS4zIG1pbyksIEFjdGlvbiAoMTI4LjE4IG1pbykgdW5kIFB1enpsZSAoMTI0Ljg4IG1pbykuIHZlcmthdWZlbiBzaWNoIGltbWVybm9jaCBkZXV0bGljaCBiZXNzZXIgYWxzIGRpZSBlbnRzcHJlY2hlbmRlbiBTcGllbGVnZW5yZXMgZGVyIEtvbmt1cnJlbnogRUEuIEFtIGRldXRsaWNoc3RlbiBpc3QgZGVyIFVudGVyc2NoaWVkIHZlcm11dGxpY2ggYmVpIGRlbiBnYW56ICJrbGVpbmVuIiBHZW5yZXMgU2ltdWxhdGlvbiAoODUuMjcgbWlvKSwgU2hvb3RlciAoNjkuNzMgbWlvKSwgRmlnaHRpbmcgKDUzLjM1IG1pbykgdW5kIEFkdmVudHVyZSAoMzUuNzEpLiBBdWNoIHdlbm4gZGllc2Ugc2ljaCBuaWNodCBhbiBkZXIgRXhha3QgZ2xlaWNoZW4gc3RlbGxlIGluIGRlciBSYW5nbGlzdGUgZGVyIFNhbGVzIGJlZmluZGVuIGhhdCBkZXIgbGV0enRlIFBsYXR6IHZvbiBOaW50ZW5kbyBTdHJhdGVneSAoMjcuMzUlKSBkZW5ub2NoIG1laHIgYWxzIGRhcyA2IEZhY2hlIGFuIFNhbGVzIGFscyBkZXIgdm9uIEVBLiBUcm90eiBkYXMgTmludGVuZG8gbWVociBUb3RhbCBTYWxlcyBoYXQgYWxzIEVsZWN0cm9uaWMgQXJ0cyBpc3QgZGllc2VyIHdlcnQgbmljaHQgNiBtYWwgc28gZ3Jvw58gc29uZGVybiB1bWZhc3N0IG5pY2h0bWFsIGRhcyBkb3BwZWx0ZS4NCg0KIyMjIyBBbnphaGwNCmBgYHtyIHBsb3QoQW1vdW50R2VucmVieVB1Ymxpc2hlck5pbnRlbmRvMSksIGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdtYXJrdXAnLCB9DQoNCmdyb3VwZWQgPC0gdmdzYWxlcyAgJT4lIA0KICBncm91cF9ieShQdWJsaXNoZXIsR2VucmUpICU+JSANCiAgc3VtbWFyaXplKEFuemFobCA9bigpKSAgJT4lIA0KICBmaWx0ZXIoUHVibGlzaGVyID09ICJOaW50ZW5kbyIpDQoNCg0KDQpheCA8LSBsaXN0KA0KICB0aXRsZSA9ICJHZW5yZSINCikNCg0KYXkgPC0gbGlzdCgNCiAgdGl0bGUgPSAiQW56YWhsIg0KDQopDQoNCg0KDQpncm91cGVkJT4lDQogIHBsb3RfbHkoKSAlPiUgYWRkX2JhcnMoeD1+R2VucmUsDQogICAgICAgICAgIHk9fkFuemFobCwNCiAgICAgICAgICAgY29sb3I9fkdlbnJlICxjb2xvcnMgPSBteVBhbGV0dGUpICAlPiUgDQogIGxheW91dCh0aXRsZT0iQW56YWhsIGRlciBTcGllbGVyZWxlYXNlcyBuYWNoIEdlbnJlIGbDvHIgTmludGVuZG8iLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXksDQogICAgICAgICBiYXJtb2RlID0gJ3N0YWNrJywNCiAgICAgICAgIHNob3dsZWdlbmQgPSBGQUxTRQ0KICAgICAgICAgKQ0KDQpgYGANCg0KSW0gZXJzdGVuIE1vbWVudCBmw6RsbHQgZGlyZWt0IGF1ZiwgZGFzcyBkZXIgQXVzc2NobGFnIHZvbiBQbGF0Zm9ybSAoMTEyKSBoaWVyIGRldXRsaWNoIGdlcmluZ2VyIGF1c2bDpGxsdCBhbHMgbm9jaCBpbiBkZW4gVmVya2F1ZnN6YWhsZW4uIFNvd29obCBSb2xlLVBsYXlpbmcgKDEwNikgYWxzIGF1Y2ggTWlzYyAoMTAwKSB1bWZhc3NlbiBudXIgZWluIHBhYXIgd2VuaWdlciBTcGllbGUuIEF1Y2ggZGFzIE1pdHRlbGZlbGQgdW1mYXNzdCBtaXQgQWN0aW9uICg3OSksIFB1enpsZSAoNzQpIHVuZCBTcG9ydHMgKDU1KSBpbW1lcm5vY2ggZWluZSBSZWxhdGl2IGdyb8OfZSBBbnphaGwgYW4gU3BpZWxlbi4gU2VsYnN0IGRpZSBoaW50ZXJlbiBQbMOkdHplIG1pdCBSYWNpbmcgKDM3KSwgQWR2ZW50dXJlICgzNSkgdW5kIFN0cmF0ZWd5ICgzMikgc2luZCBudXIga25hcHAgdm9yIFNpbXVsYXRpb24gKDI5KSwgU2hvb3RlciAoMjYpIHVuZCBGaWdodGluZyAoMTgpLg0KDQojIyMgS3JlaXNkaWFncmFtbWUgey50YWJzZXR9DQoNCiMjIyMgVmVya2F1ZnN6YWhsZW4NCg0KYGBge3IgcGxvdChHZW5yZWJ5UHVibGlzaGVyTmludGVuZG8yKSwgZWNobyA9IFRSVUUsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J21hcmt1cCcsIH0NCg0KDQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoUHVibGlzaGVyLEdlbnJlKSAlPiUgDQogIHN1bW1hcml6ZShzdW0oR2xvYmFsX1NhbGVzKSkgICU+JQ0KcmVuYW1lKA0KICAgIEdsb2JhbF9TYWxlcyA9ICJzdW0oR2xvYmFsX1NhbGVzKSINCiAgICApICU+JSANCiAgZmlsdGVyKFB1Ymxpc2hlciA9PSAiTmludGVuZG8iKQ0KDQoNCmdyb3VwZWQkR2xvYmFsX1NhbGVzPC1hc192ZWN0b3IoZ3JvdXBlZCRHbG9iYWxfU2FsZXMpDQoNCmF4IDwtIGxpc3QoDQogIHRpdGxlID0gIkdlbnJlIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJWZXJrw6R1ZmUgKGluIG1pbykiDQoNCikNCg0KZ3JvdXBlZCU+JQ0KICBwbG90X2x5KCkgJT4lIA0KICBhZGRfcGllKHZhbHVlcyA9fkdsb2JhbF9TYWxlcyxsYWJlbHM9fkdlbnJlLHRleHRpbmZvPSdsYWJlbCtwZXJjZW50Jyxzb3J0ID0gVFJVRSwNCiAgICAgICAgICAgbmFtZT0iVmVya8OkdWZlIG5hY2ggR2VucmUgZsO8ciBOaW50ZW5kbyIgLGNvbG9ycyA9IG15UGFsZXR0ZSkgJT4lIA0KICBsYXlvdXQodGl0bGU9IlZlcmvDpHVmZSBuYWNoIEdlbnJlIGbDvHIgTmludGVuZG8iLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXksDQogICAgICAgICBzaG93bGVnZW5kID0gRkFMU0UsDQogICAgICAgICBhdXRvc2l6ZSA9IEYNCiAgICAgICAgICkNCg0KDQpgYGANCg0KV2llIGJlcmVpdHMgaW4gZGVyIFtHZW5yZWFuYWx5c2UgZGVyIFB1Ymxpc2hlcl0oI0dlbnJlQnlQdWJsaXNoZXJHbG9iYWwpIGZlc3RnZXN0ZWxsdCB2ZXJrYXVmZW4gc2ljaCBQbGF0Zm9ybS1TcGllbGUgKDIzLjklKSBmw7xyIE5pbnRlbmRvIGFtIGJlc3Rlbi4gRG9jaCBhdWNoIFJvbGUtUGxheWluZyAoMTUuOSUpLCBTcG9ydHMgKDEyLjIlKSB1bmQgTWlzYyAoMTAuMSUpIG1hY2hlbiBrZWluZW4gdW53ZXNlbnRsaWNoZW4gVGVpbCBpaHJlciBWZXJrw6R1ZmUgYXVzLiBTZWxic3QgZGllIHdlbmlnZXIgUHJvbWluZW50ZW4gR2VucmVzIHdpZSBSYWNpbmcgKDguNDclKSwgQWN0aW9uICg3LjE3JSkgdW5kIFB1enpsZSAoNi45OSUpLiB2ZXJrYXVmZW4gc2ljaCBpbW1lcm5vY2ggZGV1dGxpY2ggYmVzc2VyIGFscyBkaWUgZW50c3ByZWNoZW5kZW4gU3BpZWxlZ2VucmVzIGRlciBLb25rdXJyZW56IEVBLiBBbSBkZXV0bGljaHN0ZW4gaXN0IGRlciBVbnRlcnNjaGllZCB2ZXJtdXRsaWNoIGJlaSBkZW4gZ2FueiAia2xlaW5lbiIgR2VucmVzIFNpbXVsYXRpb24gKDQuNzclKSwgU2hvb3RlciAoMy45JSksIEZpZ2h0aW5nICgyLjk5JSkgdW5kIEFkdmVudHVyZSAoMiUpLiBBdWNoIHdlbm4gZGllc2Ugc2ljaCBuaWNodCBhbiBkZXIgRXhha3QgZ2xlaWNoZW4gc3RlbGxlIGluIGRlciBSYW5nbGlzdGUgZGVyIFNhbGVzIGJlZmluZGVuIGhhdCBkZXIgbGV0enRlIFBsYXR6IHZvbiBOaW50ZW5kbyBTdHJhdGVneSAoMS41MyUpIGRlbm5vY2ggbWVociBhbHMgZGFzIDYgRmFjaGUgYW4gU2FsZXMgYWxzIGRlciB2b24gRUEuIFRyb3R6IGRhcyBOaW50ZW5kbyBtZWhyIFRvdGFsIFNhbGVzIGhhdCBhbHMgRWxlY3Ryb25pYyBBcnRzIGlzdCBkaWVzZXIgd2VydCBuaWNodCA2IG1hbCBzbyBncm/DnyBzb25kZXJuIHVtZmFzc3QgbmljaHRtYWwgZGFzIGRvcHBlbHRlLg0KDQojIyMjIEFuemFobA0KDQpgYGB7ciBwbG90KEFtb3VudEdlbnJlYnlQdWJsaXNoZXJOaW50ZW5kbzIpLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nbWFya3VwJywgfQ0KDQpncm91cGVkIDwtIHZnc2FsZXMgICU+JSANCiAgZ3JvdXBfYnkoUHVibGlzaGVyLEdlbnJlKSAlPiUgDQogIHN1bW1hcml6ZShBbnphaGwgPW4oKSkgICU+JSANCiAgZmlsdGVyKFB1Ymxpc2hlciA9PSAiTmludGVuZG8iKQ0KDQoNCmF4IDwtIGxpc3QoDQogIHRpdGxlID0gIkdlbnJlIg0KKQ0KDQpheSA8LSBsaXN0KA0KICB0aXRsZSA9ICJBbnphaGwiDQoNCikNCg0KZ3JvdXBlZCU+JQ0KICBwbG90X2x5KCkgJT4lIA0KICBhZGRfcGllKHZhbHVlcyA9fkFuemFobCxsYWJlbHM9fkdlbnJlLHRleHRpbmZvPSdsYWJlbCtwZXJjZW50Jyxzb3J0ID0gVFJVRSwNCiAgICAgICAgICAgbmFtZT0iQW56YWhsIG5hY2ggR2VucmUgZsO8ciBOaW50ZW5kbyIgLGNvbG9ycyA9IG15UGFsZXR0ZSkgJT4lIA0KICBsYXlvdXQodGl0bGU9IkFuemFobCBuYWNoIEdlbnJlIGbDvHIgTmludGVuZG8iLA0KICAgICAgICAgeGF4aXMgPSBheCwNCiAgICAgICAgIHlheGlzID0gYXksDQogICAgICAgICBzaG93bGVnZW5kID0gRkFMU0UNCiAgICAgICAgICkNCg0KYGBgDQoNCkltIGVyc3RlbiBNb21lbnQgZsOkbGx0IGRpcmVrdCBhdWYsIGRhc3MgZGVyIEF1c3NjaGxhZyB2b24gUGxhdGZvcm0gKDE1LjklKSBoaWVyIGRldXRsaWNoIGdlcmluZ2VyIGF1c2bDpGxsdCBhbHMgbm9jaCBpbiBkZW4gVmVya2F1ZnN6YWhsZW4uIFNvd29obCBSb2xlLVBsYXlpbmcgKDE1LjElKSBhbHMgYXVjaCBNaXNjICgxNC4xJSkgdW1mYXNzZW4gbnVyIGVpbiBwYWFyIHdlbmlnZXIgU3BpZWxlLiBBdWNoIGRhcyBNaXR0ZWxmZWxkIHVtZmFzc3QgbWl0IEFjdGlvbiAoMTEuMiUpLCBQdXp6bGUgKDEwLjUlKSB1bmQgU3BvcnRzICg3LjgyJSkgaW1tZXJub2NoIGVpbmUgUmVsYXRpdiBncm/Dn2UgQW56YWhsIGFuIFNwaWVsZW4uIFNlbGJzdCBkaWUgaGludGVyZW4gUGzDpHR6ZSBtaXQgUmFjaW5nICg1LjI2JSksIEFkdmVudHVyZSAoNC45OCUpIHVuZCBTdHJhdGVneSAoNC41NSUpIHNpbmQgbnVyIGtuYXBwIHZvciBTaW11bGF0aW9uICg0LjEzJSksIFNob290ZXIgKDMuNyUpIHVuZCBGaWdodGluZyAoMi41NiUpLg0KDQoNCiMjIHstfQ0KDQpCZWltIHZlcmdsZWljaGVuIGRlciBXZXJ0ZSB2b24gTmludGVuZG8gd2lyZCBlaW5lbSBhdWZtZXJrc2FtZW4gYmVvYmFjaHRlciB6aWVtbGljaCBzY2huZWxsIGtsYXIsIGRhc3MgUGxhdGZvcm0gU3BpZWxlIGVpbiBLYXNzZW5jaGxhZ2VyIHNpbmQuIE5laG1lbiBkaWVzZSBudXIgMTYlIGRlciBzcGllbGVyZWxlYXNlcyBlaW4gc28gYnJpbmdlbiBzaWUgZGVubm9jaCAyNCUgZGVyIFNhbGVzIGVpbi4gR2xlaWNoZXMgR2lsdCBmw7xyIFNwb3J0IGdhbWVzLiA4JSBnZWdlbsO8YmVyIDEyJS4gQWN0aW9uICgxMSUgdnMgNyUpLCBNaXNjICgxNCUgdnMgMTAlKSB1bmQgUHV6emxlIEdhbWVzICgxMC41JSB2cyA3JSkgc2luZCBqZWRvY2ggbmljaHQgc28gZXJmb2xncmVpY2guIERpZSBGcmFnZSB3b3JhbiBkaWVzIGxpZWdlbiBrw7ZubnRlIHfDpHJlIGJlc3RpbW10IGF1Y2ggZWluZSBpbnRlcmVzc2FudGUgdW5kIGV0d2FzIGbDvHIgZWluZW4gW0F1c2JsaWNrIGluIGRpZSBadWt1bmZ0XSgjQXVzYmxpY2tJbkRpZVp1a3VuZnQpDQoNCioqKg0KDQoNCiMgQXVzYmxpY2sgaW4gZGllIFp1a3VuZnQgeyNBdXNibGlja0luRGllWnVrdW5mdH0NCg0KQmVpIGRlciBBbmFseXNlIGRlcyBEYXRlbnNhdHplcyBiZXppZWh1bmdzd2Vpc2UgZGVyIEVudHN0YW5kZW5lbiBHcmFmaWtlbiBzaW5kIHNvd29obCBkZW0gQXVmbWVya3NhbWVuIGxlc2VyIGFscyBhdWNoIG1pciBkZW0gRXJzdGVsbGVyIGVpbmlnZSB3ZWl0ZXIgSWRlZW4gYmV6aWVodW5nc3dlaXNlIHdlaXRlcmUgQW5zw6R0emUgZ2Vrb21tZW4gZGllIG1pdCBzaWNoZXJoZWl0IGludGVyZXNzYW50IHfDpHJlbiB6dSBWZXJmb2xnZS4gRWluaWdlIGRpZXNlciBCZWlzcGllbGUgaGFiZSBpY2ggaW0gRm9sZ2VuZGVuIGFscyBJZGVlbiBmw7xyIFp1a8O8bmZ0aWdlIFByb2pla3RlIE5pZWRlcmdlc2NocmllYmVuLiANCg0KKiBCZWltIFZlcmdsZWljaCBkZXIgYWxsZ2VtZWluZW4gW0dhbWUgU2FsZXNdKCNWaWRlb0dhbWVSZWxlYXNlcykgaGFiZW4gd2lyIGF1c3NjaGzDpGdlIEZlc3RnZXN0ZWxsdCBkaWUgbcO2Z2xpY2hlcndlaXNlIGV0d2FzIG1pdCBiZXN0aW1tdGVuIFZpZGVvc3BpZWxlbiBvZGVyIGFuZGVyZSDDpHXDn2VyZW4gRWluZmx1c3NmYWt0b3JlbiB3aWUgZGVuIGVpbmZhY2hlcmVuIFp1Z3JpZmYgYXVmIEtvbnNvbGVuLCBlaW5lIGJyZWl0ZXJlIEFremVwdGFueiBmw7xyIFZpZGVvc3BpZWxlIG9kZXIgZGllIEVudHdpY2tsdW5nIGRlcyBJbnRlcm5ldHMuIEVpbmUgZ2VuYXVlcmUgQW5hbHlzZSBkZXIgQXVzc2NobMOkZ2Ugd8OkcmUgZGVtZW50c3ByZWNoZW5kIGVpbiBJbnRlcmVzc2FudGVzIFRoZW1hLg0KDQoqIEludGVyZXNzYW50IHfDpHJlIERlbXRuc3ByZWNoZW5kIGF1Y2ggZWluZSBnZW5hdWVyZSBBbmFseXNlIGRlciBHYW1lc2FsZXMgcHJvIEphaHIgYWxzbyBpbiB3ZWxjaGVtIEphaHIgd2VsY2hlcyBTcGllbCB3aWUgb2Z0IGdla2F1ZnQgd3VyZGUuIFd1cmRlIEJlaXNwaWVsc3dlaXNlIFRldHJpcyAxOTUwIDMwIG1hbCB1bmQgMjAxNSAzMDAuMDAwIG1hbCB2ZXJrYXVmdC4gRGllcyBnZWJlbiBkaWUgdm9ybGllZ2VuZGVuIERhdGVuIGplZG9jaCBsZWlkZXIgbmljaHQgaGVyIGFsc28gd8OkcmUgZWluIGFuZGVyZSBEYXRlbnNhdHogYnp3IHdlaXRlcmUgRGF0ZW4gbm90d2VuZGlnLg0KDQoqIEltIGdsZWljaGVuIEdlZGFua2Vuc2Nocml0dCBrb21tdCBlaW5lIGFuYWx5c2UgZGVyIFZlcsOkbmRlcnVuZ2VuIGltIEthdWZ2ZXJoYWx0ZW4gd8OkaHJlbmQgZGVyIENyb25hcGFuZGVtaWUgdW5kIGRlbSBkYXJhdWYgZm9sZ2VuZGVuIExvY2tkb3duIGlzdCBhYmVyIGF1cyBnbGVpY2hlbSBHcnVuZCBsZWlkZXIgbmljaHQgbcO2Z2xpY2guDQoNCiogRGFzIEdsZWljaGUgVHJpZmZ0IGF1ZiBkaWUgW1ZlcmthdWZzemhsZW50d2lja2x1bmcgaW0gbGF1ZmUgZGVyIEphaHJlXSgjU2FsZXNQZXJQbGF0Zm9ybSkgbWl0IGVpbmVyIGdlbmF1ZXJuIEFuYWx5c2UgZGVyIHZlcmthdWZ0ZW4gU3BpZWxlIHBybyBQbGF0Zm9ybSBpbSBsYXVmZSBkZXIgSmFocmUgenUuDQoNCiogRGVzd2VpdGVyZW4gaGFiZW4gd2lyIHVucyBiZWltIHZlcmdsZWljaCAgZGVyIFtQbGF0Zm9ybWVuXSgjUGxhdGZvcm1hbmFseXNlKSBkaWUgRnJhZ2UgZ2VzdGVsbHQgd2llIHNpY2ggZGllIFNwaWVsZXZlcmvDpHVmZSBwcm8gUGxhdGZvcm0gdmVyaGFsdGVuLiBFaW4gVmVyZ2xlaWNoIGViZW5qZW5lciBEYXRlbiB3w6RocmUgZGVtZW50c3ByZWNoZW5kIGludGVyZXNzYW50IHVtIHp1IGtsw6RyZW4gb2Igc2ljaCBCaWVzcGllbHN3ZWlzZSBOaW50ZW5kb3NwaWVsZSBiZXNzZXIgYXVmIE5pbnRlbmRvIGtvbnNvbGVuIG9kZXIgU29ueSBTcGllbGUgYmVzc2VyIGF1ZiBkZXIgUGxheXN0YXRpb24gdmVya2F1ZmVuLiBEaWVzIGJlbsO2dGlndCBqZWRvY2ggdm9yYWxsZW0gYXVmZ3J1bmQgdm9uIEV4a2x1c2l2dGl0ZWxuIHdpZSAiVGhlIExlZ2VuZCBvZiBaZWxkYTogQnJlYXRoIG9mIHRoZSBXaWxkIiBvZGVyICJHb2Qgb2YgV2FyIiBleHRlbnNpdmUgYW5hbHlzZWFyYmVpdC4NCg0KKiBJbiBkZXIgW1B1Ymxpc2hlcmFuYWx5c2VdKCNQdWJsaXNoZXJSZWxlYXNlcykgaGFiZW4gd2lyIHVucyBBbnphaGwgZGVyIFNwaWVsZXJlbGVhc2VzIHNvd2llIEFuemFobCBkZXIgVmVya8OkdWZlIHZlcmdsaWNoZW4uIEludGVycmVhbnQgd8OkaHJlIGhpZXIgZWluIGRpcmVrdGVyIDEgenUgMSB2ZXJnbGVpY2ggbcO2Z2xpY2hlcndlaXNlIHNvZ2FyIHVudGVyIGJlenVnbmFobWUgYXVmIFBsYXRmb3JtZW4gdW5kIEdlbnJlcy4NCg0KKiBFaW4gdmVyZ2xlaWNoIGRlciBTcGllbGUgbmFjaCBIZXJzdGVsbGVycmVnaW9uIGluIGRlciBbUGxhdGZvcm1hbmFseXNdKCNQbGF0Zm9ybWFuYWx5c2UpIHfDpHJlIHNlaHIgaW50ZXJlc3NhbnQgZ2V3ZXNlbiBpc3QgamVkb2NoIGFuaGFuZCBkZXMgRGF0ZW5zYXR6ZXMgbGVpZGVyIG5pY2h0IG3DtmdsaWNoLiBTZWxic3QgZWluZSBhbm5haG1lIGRlcyBIZXJrdW5mdHNsYW5kZXMgYW5oYW5kIGRlcyBQdWJsaXNoZXJzIGlzdCBuaWNodCBtw7ZnbGljaCBkYSB2aWVsZSBQdWJsaXNoZXIgU3R1ZGlvcyBpbiB1bnRlcnNjaGllZGxpY2hzdGVuIEzDpG5kZXJuIHVuZCBSZWdpb25lbiBiZXRyZWlidC4gVWJpc29mdCBoYXQgYmVpc3BpZWxzd2Vpc2UgU3RhbmRvcnRlIGluIFBhcmlzLCBNYWlueiwgTmV3IFlvcmsgdW5kIFNpbmdhcHVyLg0KDQoqIEVpbiBSZWdpb25hbGVyIHZlcmdsZWljaCBhbmhhbmQgZGVyIEVpbndvaG5lcnphaGxlbiBlaW5lciBSZWdpb24gYnp3IGFsbGdlbWVpbiBlaW4gVmVyZ2xlaWNoIGRlciBTcGllbGV2ZXJrw6R1ZmUgbWl0IGRlciBFbnR3aWNrbHVuZyBkZXIgV2VsdGJldsO2bGtlcnVuZywgd2VsY2hlIHNpY2ggc2VpdCAxOTgwIFtmYXN0IHZlcmRvcHBlbHQgaGF0XShodHRwczovL2RlLnN0YXRpc3RhLmNvbS9zdGF0aXN0aWsvZGF0ZW4vc3R1ZGllLzE2OTQvdW1mcmFnZS9lbnR3aWNrbHVuZy1kZXItd2VsdGJldm9lbGtlcnVuZ3N6YWhsLykuDQoNCkRpZXMgaXN0IG51ciBlaW4ga2xlaW5lciBhdXNzY2huaXR0IGRlciBzY2hpZXIgdW5lbmRsaWNoZW4gTcO2Z2xpY2hrZWl0ZW4gZGllIGVpbmVtIGJlaSBkZXIgQW5hbHlzZSB2b24gZGVuIG1pdHRsZXJ3ZWlsZSBtZWhyIGFscyA0IG1pbyBWaWRlb3NwaWVsZW4gYmxlaWJ0IHVuZCBkYXMgbnVyIGFuZ2Vub21tZW4gd2lyIGJsZWliZW4gYmVpIGVpbmVtIGVoZXIgYWxsZ2VtZWluZXJlbSBWZXJnbGVpY2guIEplZGVzIGRpZXNlciBWaWRlb3NwaWVsZSBoYXQgdmVybXV0bGljaCBnZW51ZyDDtmZmZW50bGljaGUgRGF0ZW4gdW0gZWluZSBBcmJlaXQgenUgcHJvZHV6aWVyZW4gZGllIGVpbiB2aWVsZmFjaGVzIGRlcyBWb2x1bWVucyBkaWVzZXIgQXJiZWl0LCBmw7xyIHdlbGNoZSBtaXIgbnVyIGtuYXBwIDcwaCB6dSBWZXJmw7xndW5nIHN0YW5kZW4sIGhhdC4NCg0KIyBBdWZnZXRyZXRlbmUgUHJvYmxlbWUgeyNBdWZnZXRyZXRlbmVQcm9ibGVtZX0NCg0KTnVuIGFiZXIgenUgZGVtIHVuc2Now7ZuZW4gdGVpbCBlaW5lciBqZWRlciBBcmJlaXQuIERlbiBhdWZnZXRyZXRlbmVuIFByb2JsZW1lbiwgd2VsY2hlIGVudHdlZGVyIG5pY2h0IGzDtnNiYXIgb2RlciBlaW5lIHJlbGF0aXYgc3RhcmtlIMO8YmVyYXJiZWl0dW5nIGRlciBBdXNhcmJlaXR1bmcgbmFjaHppZWhlbiB3w7xyZGVuLg0KDQoqIERhcyBFcnN0ZSB1bmQgZsO8ciBkZW4gQXVmbWVya3NhbWVuIExlc2VyLCB3ZWxjaGVyIHNpY2ggdm9yYWxsZW0gZGllIExpbmUgUGxvdHMgaW0gZGlyZWt0ZW4gdmVyZ2xlaWNoIGFuZ2VzY2hhdXQgaGF0LCBvZmZlbnNpY2h0bGljaGUuIERlciBhbSBBbmZhZyBlcnN0ZWxsdGUgQ29sb3JicmV3ZXIsIHdlbGNoZXIgZGllIEZhcmJlbiBmw7xyIGRpZSBHcmFmaWtlbiBsaWVmZXJ0IHdpcmQgYXVzIGlyZ2VuZGVpbmFtIEdydW5kIG5pY2h0IGluIGplZGVyIEdyYWZpayBha3plcHRpZXJ0LiBEaWVzIHNjaGVpbnQgaGllciByZWluIHp1ZsOkbGxpZyB6dSBzZWluIHVuZCBmb2xndCBrZWluZW0gb2ZmZW5zaWNodGxpY2hlbSBQYXR0ZXJuLiBEZXIgRWluemlnZXIgdW50ZXJzY2hpZWQgendpc2NoZW4gRmlsbGVkIExpbmVzIHVuZCBTdGFja2VkIExpbmVzIGlzdCBkaWUgQWJ3ZXNlbmhlaXQgZGVzICpmaWxsKiBwYXJhbWV0ZXJzIHVuZCBzdGF0dGRlc3NlbiBkaWUgdmVyd2VuZHVuZyB2b24gKnN0YWNrZ3JvdXA9J29uZScqLiBUcm90eiBkaWVzZW4gbWluaW1hbGVuIHVudGVyc2NoaWVkZXMgQWt6ZXB0aWVydCBkaWUgRmlsbGVkIExpbmVzIEdyYWZpayBkaWUgRmFyYmF1c3dhaGwsIFN0YWNrZWQgTGluZXMgamVkb2NoIG5pY2h0Lg0KDQoqIEVpbiB3ZWl0ZXJlciBtaXIgdW5lcmtsw6RybGljaGVyIEZlaGxlciBpbiBkZXIgRG9rdW1lbnRlcnN0ZWxsdW5nIGlzdCBkaWUgw6RuZGVydW5nIGRlcyBGb3JtYXRzIG5hY2ggZGVtIGltcG9ydGllcmVuIGRlciBMaWJyYXJ5cy4gRXMgZ2lidCBrZWluZW4gb2ZmZW5zaWNodGxpY2hlbiBHcnVuZCB3YXJ1bSBzaWNoIGhpZXIgZGFzIEZvcm1hdCDDpG5kZXJuIHNvbGx0ZSBhdWYgZWlubWFsIGbDvGxsdCBkZXIgVGV4dCBqZWRvY2ggMTAwJSBkZXMgQmlsZHNjaGlybXMgd2FzIHouVC4genUgc2VociBzY2h3ZXIgenUgbGVzZW5lZGVuIFdvcnRlbiBmw7xocnQuDQoNCiogV2llIGJlcmVpdHMgaW4gZGVyIEFuYWx5c2UgZGVyIFtTYWxlcyBwZXIgR2FtZSBwZXIgWWVhcl0oI0dlbnJlU2FsZXNQZXJHYW1lUGVyWWVhcikgZmVzdGdlc3RlbGx0IHdlcmRlbiBTcGllbGUgaMOkdWZpZyBhdWYgbWVocmVyZW4gS29uc29sZW4gdmVyw7ZmZmVudGxpY2h0LiBFaW5lIHp1c2FtbWVuZmFzc3VuZyBkZXIgU3BpZWxlIHp1bSBad2VjayBkZXIgW1NhbGVzIHBlciBHYW1lXSgjVmlkZW9HYW1lUmVsZWFzZXMpIEFuYWx5c2Ugd8OkcmUgZGFmw7xyIHZvbm7DtnRlbi4NCg0KKiBCZWkgQmV0cmFjaHR1bmcgZGVzIENvZGVzLCB3ZWxjaGVyIGRpZSBHcmFmaWtlbiBlcnpldWd0IHdpcmQgZGVuIG1laXN0ZW4gYXVmZmFsbGVuLCBkYXNzIG9mdCBkb3BwZWx0ZXIgQ29kZSBkdXJjaCB2ZXJ3ZW5kdW5nIGluIG1laHJlcmVuIERpYWdyYW1tZW4gbWl0IG51ciBsZWljaHRlbiDDhG5kZXJ1bmdlbiBlbnRzdGVodC4gWnVzYW1tZW5mYXNzdW5nIGlzdCBoaWVyIGR1cmNoIGRpZSBOdXR6dW5nIHZvbiBtZWhyZXJlbiBEYXRhIEZyYW1lcyB1bmQgYW53ZW5kdW5nIGRlciBqZXdlaWxpZ2VuIGR1cmNoYXVzIG3DtmdsaWNoIGJlbsO2dGlndCBqZWRvY2ggenVtIFRlaWwgZ3JhdmllcmVuZGUgw7xiZXJhcmJlaXR1bmcgZGVyIGVpbnplbG5lbiBBYnNjaG5pdHRlLg0KDQoNCiogRWluIEZpbHRlcm4gZGVyIFtQbGF0Zm9ybXZlcmvDpHVmZSBwcm8gSmFocl0oI1NhbGVzUGVyUGxhdGZvcm0pIG5hY2ggdG90YWwgU2FsZXMgd8OkcmUgZGV1dGxpY2ggYmVzc2VyIGFscyBlaW4gRmlsdGVybiBuYWNoIGRlbiBTYWxlcyBpbiBlaW5lbSBKYWhyLiBEaWVzIHfDvHJkZSBkaWUgRXJ6ZXVndW5nIGVpbmVzIHp1c8OkdHpsaWNoZW4gRGF0YSBGcmFtZXMgYmVuw7Z0aWdlbiB3w6RyZSBqZWRvY2ggZGV1dGxpY2ggaW5mb3JtYXRpdmVyIGFscyBkZXIgYWt0dWVsbGUgc3RhbmQgYmVpIGRlbSBlaW5pZ2UgSmFocmUgZ2FueiBhdXMgZGVtIFNoZW1hIGZhbGxlbi4NCg0KKiBEYXMgW1B1Ymxpc2NoZXIgUmFua2luZyBuYWNoIFJlZ2lvbl0oI1B1Ymxpc2hlclJhbmtpbmdieVJlZ2lvbikgd8O8cmRlIHZlcm11dGxpY2ggdm9yYWxsZW0gZGllIGtsZWluZXJlIFJlZ2lvbiBKYXBhbiBlaW5lbiBkZXV0bGljaCBhbmRlcmVuIGF1c2dhbmcgYXVmemVpZ2VuLCBzb2xsdGUgbmljaHQgbmFjaCBkZXIgQW56YWhsIGRlciBTcGllbGUgc29uZGVybiBiZWlzcGllbHN3ZWlzZSBkZW0gd2VydCBkZXIgVmVya2F1ZnN6YWhsZW4gZ2VmaWx0ZXJ0IHdlcmRlLiBEaWVzIGbDvGhydCBqZWRvY2ggZGF6dSwgZGFzcyB1bnRlcnNjaGllZGxpY2hlbiBQdWJsaXNoZXIgdmVyZ2xpY2hlbiB3ZXJkZW4gd2FzIGRlbiBpbmZvcm1hdGlvbnNnZWhhbHQgbWluaW1pZXJlbiB3w7xyZGUuDQoNCiogQmVpIGRlciBbUGxhdGZvcm1hbmFseXNdKCNQbGF0Zm9ybWFuYWx5c2UpIHdpcmQgZGVuIG1laXN0ZW4sIHZvcmFsbGVtIG5pY2h0IEdhbWluZ3ZlcnNpZXJ0ZW4gTGVzZXJuIGF1ZmdlZmFsbGVuIHNlaW4gZGFzIE1vYmlsZWdhbWVzIGltIERhdGVuc2F0eiBrb21wbGV0dCBmZWhsZW4uIEFscyBkaWUgd29obCBhbSB3ZWl0IHZlcnRyZXRlbnN0ZSB1bmQgbWl0dGxlcndlaWxlIFt1bXNhdHpzdMOkcmtzdGVdKGh0dHBzOi8vZGUuc3RhdGlzdGEuY29tL2luZm9ncmFmaWsvMjI0MTQvdW1zYXR6LWF1c2dld2FlaGx0ZXItc2VrdG9yZW4tZGVyLXVudGVyaGFsdHVuZ3NpbmR1c3RyaWUvKSBQbGF0Zm9ybSBiZWVpbmZsdXNzdCBkaWVzIGRlbiBEYXRlbnNhdHogdW5nZW1laW4uIEFsbGdlbWVpbiBzaW5kIG51ciBrbmFwcCAxNi4wMDAgZGVyIHdlbHR3ZWl0IG1laHIgYWxzIFszLjMgbWlvXSggaHR0cHM6Ly93d3cuc3RhdGlzdGEuY29tL3N0YXRpc3RpY3MvMjkzMzA0L251bWJlci12aWRlby1nYW1lcnMvIzp+OnRleHQ9SW4lMjB0b3RhbCUyQyUyMHRoZXJlJTIwd2VyZSUyMGFuLGJpbGxpb24lMjBnYW1lcnMlMjBhY3Jvc3MlMjB0aGUlMjBnbG9iZSkgVmlkZW9zcGllbGUgaW4gZGVtIERhdGVuc2F0eiB2b3JoYW5kZW4uDQoNCiogTnVuIHp1IFZlcm11dGxpY2ggZGVtIGdyw7bDn3RlbiBQcm9ibGVtIG5lYmVuIGRlbiBiZXJlaXRzIHZvcmhlcmlnIGV0d8OkaG50ZW4gZmVobGVuZGVuIERhdGVuLiBWaWVsZSBzcGllbGUgd2VyZGVuIGF1ZiB2ZXJzY2hpZWRlbmVuIFBsYXRmb3JtZW4sIHp1bSB0ZWlsIGF1ZiBLb25rdXJyZW50ZW4gb2RlciBuYWNoZm9sZ2VybiByZXJlbGVhc3QuIERhcyBiZWRldXRldCBkYXMgZWluIFNwaWVsIGbDvHIgbWVocmVyZSBLb25zb2xlbiB2ZXLDtmZmZW50bGljaHQgd2lyZC4gRGllc2UgRGF0ZW4gd2VyZGVtIGltIFZvcmhhbmRlbmVuIERhdGVuc2F0em5pY2h0IHp1c2FtbWVuZ2Vmw7xocnQgdW5kIGtvbW1lbiBkZW1lbnRzcHJlY2hlbmQgbWVocm1hbHMgdm9yLiBTdXBlciBNYXJpbyBicm9zIGV4aXN0aWVydCBiZWlzcGllbHN3ZWlzZSAxMyBtYWwgdW5kIEdyYW5kIFRoZWZ0IEF1dG8gNCBiZWxlZ3QgcGxhdHogNTIgYXVmIGRlciB4Ym9YMzYwIHVuZCBQbGF0eiA1NyBhdWYgZGVyIFBTMy4NCg0KIyBMaXRlcmF0dXIgdW5kIFF1ZWxsZW52ZXJ6ZWljaG5pcyB7I0xpdGVyYXR1cnZlcnplaWNobmlzfQ0KDQoqIFtMb2dvIGRlciBBcmJlaXRdKGh0dHBzOi8vZGUud2lraXBlZGlhLm9yZy93aWtpL1ZpZGVvX0dhbWVzIy9tZWRpYS9EYXRlaTpWaWRlb2dhbWVzMTk5MS0wMV8obG9nbykuc3ZnKQ0KKiBbRGF0ZW5zYXR6XShodHRwczovL3d3dy5rYWdnbGUuY29tL2RhdGFzZXRzL2dyZWdvcnV0L3ZpZGVvZ2FtZXNhbGVzICkNCiogW3Bsb3RseV0oaHR0cHM6Ly9wbG90bHkuY29tL3IvKQ0KKiBbVmlkZW8gR2FtZSBTdGF0aXN0aWsgMV0oaHR0cHM6Ly93d3cuc3RhdGlzdGEuY29tL3N0YXRpc3RpY3MvMjkzMzA0L251bWJlci12aWRlby1nYW1lcnMvIzp+OnRleHQ9SW4lMjB0b3RhbCUyQyUyMHRoZXJlJTIwd2VyZSUyMGFuLGJpbGxpb24lMjBnYW1lcnMlMjBhY3Jvc3MlMjB0aGUlMjBnbG9iZSkNCiogW1ZpZGUgR2FtZSBTdGF0aXN0aWsgMl0oaHR0cHM6Ly9kZS5zdGF0aXN0YS5jb20vaW5mb2dyYWZpay8yMjQxNC91bXNhdHotYXVzZ2V3YWVobHRlci1zZWt0b3Jlbi1kZXItdW50ZXJoYWx0dW5nc2luZHVzdHJpZSkNCiogW1JfTWFya2Rvd24gMV0oaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvYm9va2Rvd24vKQ0KKiBbUl9NYXJrZG93biAyXShodHRwczovL2hvbHR6eS5naXRodWIuaW8vUGltcC1teS1ybWQvKQ0KKiBbR2l0aHViIFZlcnplaWNobmlzIGlua2x1c2l2ZSBrb21wbGV0dGVuIFByb2pla3R2ZXJsYXVmc10oaHR0cHM6Ly9naXRodWIuY29tL0pvZHNkZXJlY2h0ZS9SX1N0dWRpb19EZWZhdWx0X3dvcmtzcGFjZSk=
Created by Florian Reichle
flre0005@hs-kl.de